Reputation: 184
I want to load two plugins to webpack: extract-text-webpack-plugin
and babel-minify-webpack-plugin
.babel-minify-webpack-plugin
should be only loaded if the environment is in production
. Currently I'm creating envPlugin
array and pushing plugins, depending on the environment flag.
module.exports = (env) => {
const isProduction = env === 'production';
const CSSExtract = new ExtractTextPlugin('styles.css');
const bundleJSMinifier = new MinifyPlugin();
let envPlugins = [CSSExtract];
if (isProduction) {
envPlugins.push(bundleJSMinifier);
}
return {
entry: ['babel-polyfill', './src/app.js'],
output: {
path: path.join(__dirname, 'public', 'dist'),
filename: 'bundle.js'
},
module: {
rules: [...]
},
plugins: envPlugins,
devtool: isProduction ? 'source-map' : 'inline-source-map',
devServer: {...}
};
};
The question is there a better way to load plugins to webpack depending on environment I'm currently in.
Upvotes: 1
Views: 1026
Reputation: 5780
You can split your production and development configuration in different files, put the common settings in a common file and use webpack-merge
plugin to merge them in each env like this:
webpack.common.js
const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: 'development',
entry: __dirname + '/admin/app/frontend/entry.js',
output: {
path: __dirname + '/admin/public/compiled',
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
include: __dirname + '/admin/app/frontend/',
use: {
loader: 'babel-loader'
}
},
{
test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
loader: 'file-loader?name=fonts/[name].[ext]'
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
},
{
test: /\.png$/,
loader: "url-loader?mimetype=image/png"
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "styles.css",
}),
new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en|de)$/)
]
};
webpack.dev.js
:
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
devtool: 'inline-source-map',
});
webpack.prod.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
plugins: [
new UglifyJSPlugin({
sourceMap: true
})
]
});
and in my package.json
I have specific commands for each env. npm watch
for development and npm build
for production. each of them points to the correct env file:
{
"name": "my-app",
"version": "1.0.0",
"description": "my app desc",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --config webpack.dev.js --watch",
"build": "webpack --config webpack.prod.js"
},
"repository": {
"type": "git",
"url": "https://repo-url"
},
"keywords": [
"bpaulino",
"bruno"
],
"engines": {
"node": "8.5.0"
},
"author": "Bruno Paulino",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-plugin-react-transform": "^2.0.2",
"babel-plugin-transform-es2015-destructuring": "^6.23.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-display-name": "^6.5.0",
"babel-polyfill": "^6.7.4",
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
...
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0",
"webpack-merge": "^4.1.0"
},
"dependencies": {
"axios": "^0.16.2",
"babel-plugin-prismjs": "^1.0.2",
"bootstrap-sass": "^3.3.7",
"history": "^4.6.3",
"lodash": "^4.17.4",
"marked": "^0.5.0",
"moment": "2.22.2",
"node-uuid": "^1.4.8",
"normalizr": "^3.2.3",
"npm": "^6.2.0",
"prismjs": "^1.15.0",
"prop-types": "^15.6.2",
"react": "^16.4.1",
...
}
}
using the webpack-merge
plugin you can override any settings defined in the common configuration.
Upvotes: 1