Unable to change the publicPath in Vue 3 with Vite.js - javascript

I am trying to change the public path for production build but can't seem to get it to work. When I build for production, I would like to change the public path from / to ./ but I could not find anything in the documentation how to do this. I am using vite.js as my build tool. Maybe this is something Vue 3 and Vite specific, I'm not sure.
I have tried adding a vue.config.js file and also .env variables but so far nothing is working.
When I build, I get this output with path starting with /:
<head>
<script src="/assets/index.30c61b3b.js"></script>
<link href="/assets/vendor.29497e16.js">
<link href="/assets/index.7123a98f.css">
</head>
But for production I would like it to change to ./ like this:
<head>
<script src="./assets/index.30c61b3b.js"></script>
<link href="./assets/vendor.29497e16.js">
<link href="./assets/index.7123a98f.css">
</head>
I tried adding vue.config.js but it is not helping:
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? './' : '/'
}
and also .env
NODE_ENV=production
BASE_URL=./

I found the answer, I needed to add a base option to vite.config.js like this:
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue({
reactivityTransform: true
})
],
base: './',
})
https://vitejs.dev/config/#base

Related

Unable to import css files into NextJs project

Currently I have my index.js file that has my display components. For CSS I have downloaded a css file from an external source. I am then adding the .css file into my styles folder that comes when you make the initial npx create-next-app. This file I'm then trying to import into my index.js file like so: import bootStyles from "../styles/bootstrap.css". But doing this gives me this error:
error - ./styles/bootstrap.css Global CSS cannot be imported from
files other than your Custom . Please move all global CSS imports
to pages_app.js. Or convert the import to Component-Level CSS (CSS
Modules). Read more: https://nextjs.org/docs/messages/css-global
Location: pages\index.js
Additionally I have also tried using the Head component like so:
import Head from 'next/head'
<Head>
<title>Create Next App</title>
<link rel="stylesheet" href="../styles/bootstrap.css"/>
</Head>
This doesnt show an error but the styles still dont reflect on my webpage.
Either put all your CSS imports in _app.tsx or you can add *.module.css to your filenames so they get picked up.
You can also override the nextjs webpack config:
// next.config.js
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
return config
},
}
...
{
test: /\.s?[ac]ss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
exclude: [/node_modules/],
},
In order to override the module rules and css loader, however I wouldn't recommend this if you don't know what you're doing.

String replacements in index.html in vite

I am trying to inject some strings into the index.html of a Vite app (using vue3 template). In a vue-cli project for example we would have
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
What is the Vite way to do that? (I know that BASE_URL is just '/' in this case. I am asking for the general solution) I would be fine with a solution that covers environment variables only, but it would be great to know an even more general solution that can use JS code as in
<title><%= htmlWebpackPlugin.options.title %></title>
And I would really appreciate a solution that doesn't require installing an npm package
Had to lower my expectations considerably:
I install a package
I "cheat" and use process.env
// vite.config.js
import vue from '#vitejs/plugin-vue'
import { loadEnv } from 'vite'
import { createHtmlPlugin } from 'vite-plugin-html'
export default ({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
plugins: [
vue(),
createHtmlPlugin({
minify: true,
inject: {
data: {
title: env.VITE_MY_FOO,
}
}
}),
],
}
}
then in .env
VITE_MY_FOO="Hello vite ejs"
and in index.html
<title><%= title %></title>
Can't say I like it, but it works

Vue.js / Webpack build "index.html" using a "static" subdomain for CSS and JS

I have a Vue.js project that is working fine in localhost.
But when I build and deploy to production, I need the static files (.css and .js) to be served on a "static" subdomain.
For example, my main URL:
https://www.example.com/index.html
The static assets will be:
https://static.example.com/css/app.50f83e17.css
https://static.example.com/js/chunk-vendors.6f495bf3.js
When I run "npm run build" Webpack build the "index.html" file loading like this:
<link href=/css/app.50f83e17.css rel=stylesheet>
But I need the href to be like this:
<link href=https://static.example.com/css/app.50f83e17.css rel=stylesheet>
How do I configure Vue.js or Webpack to build the "index.html" using a different subdomain for the CSS and JS?
To achieve this you would need to use webpack publicPath
You can configure webpack to build index.html using a different subdomain,
webpack.config.js
import webpack from 'webpack';
export default {
output: {
..
publicPath: 'https://static.example.com/js/',
},
};
npm run build Webpack build the "index.html" would have
..
..
<script type="text/javascript" src="https://static.example.com/js/chunk-vendors.6f495bf3.js"></script>
For css,
webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: 'https://static.example.com/css/',
},
},
'css-loader',
],
},
],
},
};
You can also specify publicPath at runtime,
entry.js
__webpack_public_path__ = myRuntimePublicPath;
// rest of your application entry
Note: please consider adding a environment variable instead of hardcoding the asset CDN path, and pass the environment variable via npm scripts, alternately you can also define a global publicPath
var myRuntimePublicPath = 'https://static.example.com/js/'
and use it in the entry file (say entry.js) as displayed above.
refer: webpack publicPath and mini-css-extract-plugin publicPath
In case of using Vue Router
The base URL your application bundle will be deployed at publicPath (known as baseUrl before Vue CLI 3.3).
vue.config.js
module.exports = {
publicPath: process.env.NODE_ENV === 'production'
? 'https://static.example.com/js/'
: '/'
}
Vue Router
// override the base to hardcoded default value as it gets the value from publicPath
base: '/'
This will allow subdomain for javaScript bundle of vuejs build.

Webpack alias in Laravel Mix to node_modules

I would like to use an alias in VUE.JS in a Laravel 5.8 project to import css and js I have in my module.
webpack.mix.js
mix.webpackConfig({
resolve: {
alias: {
'alias': path.resolve(
__dirname,
'~myModule/src'
)
}
}
});
In my VUE App.js I would like import the css folder and I wrote:
resources/js/app.js
// css files
import 'alias/lib/css'
// js files
import 'alias/lib/script'
But I'm wrong something becouse the alias is not resolved:
ERROR in ./resources/js/app.js
Module not found: Error: Can't resolve 'alias/lib/css' in...
Can you help me to fix the issue?
After so many attempts I got the issue. The code was good but I was missing to load the webpack.mix.js properly:
From Laravel Mix documentation:
The webpack.mix.js file is your entry point for all asset compilation. Think of it as a light configuration wrapper around Webpack. Mix tasks can be chained together to define exactly how your assets should be compiled.
But if you are using npm run watch it is not (re)loaded before to compile new changed assets. This means:
if you are in watch mode (npm run watch) exit and restart it to load new updated webpack.config.js if you changed it.
Finally it worked! And it resolve new alias properly!
Here the final config I used in webpack.config.js:
mix.webpackConfig({
resolve: {
alias: {
'aliasName': path.resolve(
__dirname,
'node_modules/MyModule/src/'
)
}
}
});
Another alternative is:
mix.webpackConfig({
resolve: {
modules: [
'node_modules'
],
alias: {
'aliasName' : 'MyModule/src/'
}
}
});
Then in my Vue component (or in vue app.js, just in case)
<template>
<myModule-component></myModule-component>
</template>
require('aliasName/lib/css'); // to load full css directory
require('aliasName/lib/script'); // to load full js directory
import MyModuleComponent from 'aliasName/widgets/MyModuleComponent.vue'
...
export default {
...
components: {
'myModule-component': MyModuleComponent
}

Conditionally importing npm modules?

My project structure is as follows:
- workspace
- customPackage
- customIndex.js
- myProject
- index.js
- myProject2
- index.js
In dev, I want to import the package from my local workspace like following:
//index.js
import something from '../customePackage/customIndex.js'
where as in production I need the import to work from npm modules like the following:
//index.js
import something from 'customPackage';
The purpose being to be able to use the local changes in the package(without going through the commit cycle). Finally after testing the package can be pushed and used normally via npm package.
How to do this in an efficient way without having to make code changes every time?
You can use Resolve#alias with Webpack:
resolve: {
alias: {
"customPackage": process.env.NODE_ENV === "production" ?
"customPackage" :
path.resolve(__dirname, "../customePackage/customIndex.js")
}
}
Then in your source, you only need to do:
import something from 'customPackage';
And it will point to the correct package. Obviously you need to set the NODE_ENV environment variable, or change that depending on your build environment.
if you are already using webpack you can make two different entry points:
entry: {
bundle: './Scripts/index.tsx',
bundle2: './Scripts/index2.tsx'
},
output: {
publicPath: "/js/",
path: path.join(__dirname, '/wwwroot/js/'),
filename: '[name].js'
},
then in index you import main module and in index2 import your test module. So you will have different bundle files bundle.js and bundle2.js.

Categories

Resources