Hi is it possible to make plugins in webpack configuration depending on environement?
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new CopyWebpackPlugin([
{from: 'src/www/'}
])
// new BundleAnalyzerPlugin(),
// new CompressionPlugin({
// algorithm: 'gzip',
// test: /\.js$|\.css$|\.html$/
// }),
// new UglifyJsPlugin({
// test: /\.js(\?.*)?$/i
// })
]
The commented ones should only be used if I bundle it with NODE_ENV=production
Thanks in advance
Hi is it possible to make plugins in webpack configuration depending on environement?
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new CopyWebpackPlugin([
{from: 'src/www/'}
])
// new BundleAnalyzerPlugin(),
// new CompressionPlugin({
// algorithm: 'gzip',
// test: /\.js$|\.css$|\.html$/
// }),
// new UglifyJsPlugin({
// test: /\.js(\?.*)?$/i
// })
]
The commented ones should only be used if I bundle it with NODE_ENV=production
Thanks in advance
Share Improve this question asked May 20, 2019 at 13:51 FelixFelix 5,61914 gold badges80 silver badges172 bronze badges 2- 1 You can create multi webpack config files, one for each environment you want to support. gist.github.com/Pepeye/8228bd468d5bc065fb33 – Hyyan Abo Fakher Commented May 20, 2019 at 13:55
- You can have a config file for each environment. – Kris D. J. Commented May 20, 2019 at 13:56
5 Answers
Reset to default 13Based on your requirements, add the plugins if the env is production else return false, and filter the array based on the Boolean, but the preferred way is to create a different file for the different env, it will be much cleaner approach.
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new CopyWebpackPlugin([
{from: 'src/www/'}
])
NODE_ENV==='production' ? new BundleAnalyzerPlugin() : false,
NODE_ENV==='production' ? new CompressionPlugin({
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/
}) : false,
NODE_ENV==='production' ? new UglifyJsPlugin({
test: /\.js(\?.*)?$/i
}) : false
].filter(Boolean)
Using your example I would prefer something like this:
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new CopyWebpackPlugin([
{from: 'src/www/'}
])
NODE_ENV === 'production' && new BundleAnalyzerPlugin(),
NODE_ENV === 'production' && new CompressionPlugin({
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/
}),
NODE_ENV === 'production' && new UglifyJsPlugin({
test: /\.js(\?.*)?$/i
})
].filter(n => n)
or if you prefer ES5:
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new CopyWebpackPlugin([
{from: 'src/www/'}
])
NODE_ENV === 'production' && new BundleAnalyzerPlugin(),
NODE_ENV === 'production' && new CompressionPlugin({
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/
}),
NODE_ENV === 'production' && new UglifyJsPlugin({
test: /\.js(\?.*)?$/i
})
].filter(function (plugin) { return plugin; })
What this snippet does is adding a conditional (NODE_ENV === 'production'
) to the array, which is simply telling the JS compiler to either write false
or the right-hand code to the array. The filter
function on the other hand is only saying, filter out stuff that is false
or false-ish.
Let's assume we are on NODE_ENV = 'development'
, our plugins would look like this:
[HotModuleReplacementPlugin, NamedModulesPlugin, LoaderOptionsPlugin, CopyWebpackPlugin, false, false, false].filter(...)
after the filter has made it's job, we are having this one:
[HotModuleReplacementPlugin, NamedModulesPlugin, LoaderOptionsPlugin, CopyWebpackPlugin]
If we now assume we are on NODE_ENV = 'production'
, our plugins would look like this:
[HotModuleReplacementPlugin, NamedModulesPlugin, LoaderOptionsPlugin, CopyWebpackPlugin, BundleAnalyzerPlugin, CompressionPlugin, UglifyJsPlugin].filter(...)
after the filter has made it's job, we are having this one:
[HotModuleReplacementPlugin, NamedModulesPlugin, LoaderOptionsPlugin, CopyWebpackPlugin, BundleAnalyzerPlugin, CompressionPlugin, UglifyJsPlugin]
You can have A file config per environment
webpack
├── base.config.js
└── prod.config.js
// base.config.js
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.EnvironmentPlugin([
'NODE_ENV',
]),
],
};
// prod.config.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const baseConfig = require('./base.config.js');
module.exports = merge(baseConfig, {
....
plugins: [
// Minify JS
new UglifyJsPlugin({
sourceMap: false,
compress: true,
})
],
});
then in your package.json
"scripts": {
"build": "NODE_ENV=production webpack --config webpack/prod.config.js",
"start": "NODE_ENV=development webpack-dev-server --config webpack/dev.config.js"
}
this is how i use plugin only in production
// Load this plugin only when running webpack in a production environment
if (process.env.NODE_ENV == 'production') {
module.exports.plugins.push(
new BundleAnalyzerPlugin({
analyzerPort: 4000
}),
);
}
I would go with rest operator for cleaner look:
const isDev = process.env.NODE_ENV !== 'production';
const plugins = isDev ? [
new ForkTsCheckerWebpackPlugin(),
] : [
new BundleAnalyzerPlugin({
openAnalyzer: process.env.OPEN_ANALYZER === 'true',
}),
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
DEBUG_PROD: false,
START_MINIMIZED: false,
}),
]
Then inside the configuration file:
plugins: [
...plugins,
new CopyWebpackPlugin({
patterns: [
{
from: 'source',
to: 'destination',
},
],
}),
],
Now we don't need those nasty comparisons.