We have multiple webpack configuration files, and I need to restructure them to share common configuration
Current file structure
- webpack.prod.js
- webpack.dev.js
New file structure
- webpack.common.js
- webpack.prod.js
- webpack.dev.js
The prod and dev files will use webpack-merge to merge their contents with the common file. However, there are a number of places that need different merge rules, and I have been unable to find anything clear about using different merge rules together.
Here is some sample configuration to highlight what I am trying to do
// webpack.common.js
const commonConfig = {
module: {
rules: [
{
test: /.css$/,
use: ["css-loader"]
},
]
},
plugins: [
new webpack.EnvironmentPlugin({
MY_ENV_1: "Common_value_1",
MY_ENV_2: "Common_value_2",
MY_ENV_3: "Common_value_3",
}),
],
}
// webpack.dev.js
const devConfig = {
module: {
rules: [
{
test: /.css$/,
use: ["style-loader"]
},
]
},
}
// webpack.prod.js
const prodConfig = {
module: {
rules: [
{
test: /.css$/,
use: [MiniCssExtractPlugin.loader,]
},
]
},
plugins: [
new webpack.EnvironmentPlugin({
MY_ENV_1: "Prod_value_1",
MY_ENV_2: "Prod_value_2",
}),
],
}
Here are my attempts at merging. As you can see, I have only got as far as doing each individually, as I am not happy with the individual outputs. But I would eventually like to only need a single merge, assuming that is possible.
const { mergeWithRules, mergeWithCustomize, CustomizeRule, unique } = require("webpack-merge");
const merge1 = mergeWithRules({
module: {
rules: {
test: CustomizeRule.Match,
use: CustomizeRule.Prepend,
},
},
})(commonConfig, prodConfig);
const merge2 = mergeWithCustomize({
customizeArray: unique(
"plugins",
["EnvironmentPlugin"],
(plugin) => plugin.constructor && plugin.constructor.name,
),
})(commonConfig, prodConfig);
This is the current output I produce.
// merge 1 output - I'm not clear what has happened to the test value
{
"module": {
"rules": [
{
"test": {},
"use": [
"Resolved/Path/To/loader.js,
"css-loader"
]
}
]
},
"plugins": [
{
"keys": [
"MY_ENV_1",
"MY_ENV_2",
"MY_ENV_3"
],
"defaultValues": {
"MY_ENV_1": "Common_value_1",
"MY_ENV_2": "Common_value_2",
"MY_ENV_3": "Common_value_3"
}
},
{
"keys": [
"MY_ENV_1",
"MY_ENV_2"
],
"defaultValues": {
"MY_ENV_1": "Prod_value_1",
"MY_ENV_2": "Prod_value_2"
}
}
]
}
// merge 2 output - only one set of ENV values is used
{
"module": {
"rules": [
{
"test": {},
"use": [
"css-loader"
]
},
{
"test": {},
"use": [
"Resolved/Path/To/loader.js,
]
}
]
},
"plugins": [
{
"keys": [
"MY_ENV_1",
"MY_ENV_2"
],
"defaultValues": {
"MY_ENV_1": "Prod_value_1",
"MY_ENV_2": "Prod_value_2"
} // Should also have "MY_ENV_3": "Common_value_3"
}
]
}





