How to configure Production build and Development Build vue-cli - vue.js

I want to setup a npm script for production build and one for development build. like npm run build for production and npm run buildDev for development.
I have some configurations in each env file like:
ROOT_API: '"url for the production"' and something else in the development env.
The build will be added to the dist folder.
I want the Production Build to be added to the dist folder and the Development Build to be added to a distDev folder.
I have tried to make a copy of the build.js file but without luck.
config/index.js:
'use strict'
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
build: {
env: require('./prod.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are
"buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}
config/prod.env.js
module.exports = {
NODE_ENV: '"production"',
ROOT_API: '"url for production"'
}
config/dev.env.js
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
ROOT_API: '"url for development"'
})
build/build.js
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot,
config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP
server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
Any suggestions?

Didn't you try to use vue.config.js file to configure Vue build behavior?
You could specify an outputDir according to process.env.NODE_ENV at vue.config.js.
All environment-specific parameters would be set at .env.development and .env.production files accordingly.
Of course you can modify Webpack config through vue.config.js if you need, examples here.
Output directory parameter changing example is here.
At the end, your configuration file will depend only on environment variables and maybe some logic, e.g.:
module.exports = {
NODE_ENV: process.env.NODE_ENV,
ROOT_API: process.env.VUE_APP_ROOT_API_URL,
ANY_PARAM: process.env.VUE_APP_ANY_DOT_ENV_PARAM,
}
But remember, that your custom .env params should start with VUE_APP_ prefix, if you use them at templates.

Add --mode development entry in your package.json file like this:

Related

How to migrate from node-sass to sass (dart sass) in an express app

With LibSass deprecated, I see that I should replace the node-sass library with sass. In an express app, previously, you would use the node-sass-middleware and node-sass like so:
const express = require('express');
const sassMiddleware = require('node-sass-middleware');
const path = require('path');
const app = express();
app.use(sassMiddleware({
/* Options */
src: __dirname,
dest: path.join(__dirname, 'public'),
debug: true,
outputStyle: 'compressed',
prefix: '/prefix' href="prefix/style.css"/>
}));
app.use('/public', express.static(path.join(__dirname, 'public')));
The only indication I found about how to use the sass module with express is this article. This method does not use a middleware but instead runs the sass module via a script (configured inside the packages.json file). Here is the relevant part of the article:
"scripts": {
"start": "node .",
"dev": "nodemon . & npm run scss",
"scss": "sass --watch src/scss/main.scss public/styles/main.css"
},
But my confidence in this article is low. For starters, it seems to be compiling sass only in development (the "start" script does not use the "scss" script). Also, this method does not use a middleware.
So, I guess I have 2 questions:
is there a way to use a middleware (like the old node-sass-middleware) to use the sass module with express? (It would be easier to update my code and I'm lazy...)
If not, is the example in the article the correct way to use sass with express?
I didn't want to rely on remembering to run a script manually (I would definitely forget to do it) and combining scripts with "&" (or even "&&") like in the article was not working so well for me.
I wanted to use code to launch the script, so what I did is just compile my CSS synchronously when the server starts.
Here is my code:
app.js
const express = require('express');
const path = require('path');
const { compileCss } = require('./compileCss');
const app = express();
const sassOptions = {
src: path.join(__dirname, 'public'),
dest: path.join(__dirname, 'public')
};
compileCss(sassOptions);
app.use('/public', express.static(path.join(__dirname, 'public')));
# ... rest of app.js code
compileCss.js
const sass = require('sass');
const { readdirSync , writeFileSync} = require('fs');
const path = require('path');
const compileCss = ({src, dest, ext=[".sass", ".scss"]}) => {
const srcFiles = readdirSync(src, {withFileTypes: true}).filter(dirent => dirent.isFile() && ext.includes(path.extname(dirent.name)));
for(const file of srcFiles) {
const srcFilePath = path.join(src, file.name);
const baseName = path.basename(file.name, path.extname(file.name));
const cssName = baseName + '.css';
const destFilePath = path.join(dest, cssName);
const result = sass.compile(srcFilePath);
writeFileSync(destFilePath, result.css, 'utf-8');
}
}
module.exports = { compileCss }
I haven't tested it yet, but I think if you download dart-sass-middleware and require it instead of node-sass-middleware then it should work.
This is what I ran to install it:
npm install dart-sass-middleware
More details on dart-sass-middleware can be found at https://www.npmjs.com/package/dart-sass-middleware
Let me know if it works!
Instead of node-sass-middleware you can use express-dart-sass.
Here is their repo.

Vue & Webpack - make files unreadable after build [duplicate]

My app is created with the vue cli. I can't find any option to disable source maps in production.
The npm build step in my package.json looks like this:
"build": "vue-cli-service build",
In angular, i can just add --prod to my build step to make it work.
Is there any such option for vue.js? Or do I have to change the webpack config (which is hidden by the cli)?
You make changes to the internal webpack config with the vue.config.js file at the project root (you may need to create it manually).
There is a productionSourceMap option so you can disable source maps when building for production:
module.exports = {
productionSourceMap: false
};
like #yuriy636 's answer, if you want only for production :
module.exports = {
productionSourceMap: process.env.NODE_ENV != 'production'
};
In my case the file vue.config.js wasn't taking effect. I had to change config/index.js changing productionSourceMap to false.
Please note that the project was generated a time ago. For the record, I am using a template from Vuetify.
'use strict'
// Template version: 1.2.8
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true,
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: './',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: false, // <---- Here
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}

Giving static filenames for build files in vue-cli3

I am using vue-cli3, when i build using npm run build -- --mode=production, it gives 2 css files and 2 js files.
Everytime i make a code change the name of the file also changes like app.de90cdf7.js and chunk-vendors.a9204242.js.
Is there a way in vue-cli to hardcode the files names as app.js and chunk-vendors.js ?
I'm little late to the party. We can chain webpack to apply name changes.
Using version #vue/cli 5.0.4 in year 2022
const { defineConfig } = require("#vue/cli-service");
module.exports = defineConfig({
transpileDependencies: true,
chainWebpack : (config) => {
config.output.filename('[name].js');
},
css: {
extract: {
filename: '[name].css',
chunkFilename: '[name].css'
}
}
});

I want `npm run build` generate the dist assets files in the static directory

In my src/config/index.js, the build settings is bellow:
const path = require('path')
module.exports = {
build: {
env: require('./env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
but after I npm run build, I get the results:
shouldn't the assets file in the static directory? where is the error of config?
I want the dist directory like this:
my webpack.prod.config.js default code is bellow:
......
new HtmlWebpackPlugin({
filename: '/index.html',
template: './src/template/index.ejs',
inject: false
})
]
});
the filename: '/index.html', so, the index.html is in the above of dist directory.

Custom global process.env variable with Webpack build

I have a Vue application that's compiled using Webpack. I'm trying to add a variable into the 'npm run dev' command that I can then use globally throughout the project. Currently, I am running 'npm --brand=foo run dev' and consoling 'process.env.brand' in the build.js file returns 'foo'. Now I need to make this available to the rest of the project. Here is my setup:
WEBPACK.DEV.CONF.JS
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
module.exports = merge(baseWebpackConfig, {
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
})
})
DEV.ENV.JS
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
File structure is Build/build.js + webpack.dev.conf.js and Config/dev.env.js. I tried to add a 'brand' property like the following, but process.env.brand was undefined in this file.
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
brand: process.env.brand
})
UPDATE by #Linx to pass the argument dynamically directly from
command line
Run the command and pass in the variable like: npm --brand=foo run dev
Then, variable is then available in the webpack config file as
process.env.npm_config_brand.
Another option is to setting the variable inside the npm script section:
package.json
{
//...
"scripts": {
"dev": "SET brand=foo& webpack -p"
},
If you are using linux, maybe you should remove the SET --> "dev": "brand=foo& webpack -p"
Then run the command like: npm run dev
In both cases, to make it available for the rest of the project you can use webpack.DefinePlugin
module.exports = {
//...
plugins: [
new webpack.DefinePlugin({
'__BRAND__': process.env.brand,
})
]
}
The variable will be accessible in the rest of the project like: console.log(__BRAND__);