webpack-merge - Merge designed for Webpack
webpack-merge provides a merge
function that concatenates arrays and merges objects creating a new object. If functions are encountered, it will execute them, run the results through the algorithm, and then wrap the returned values within a function again.
This behavior is particularly useful in configuring webpack although it has uses beyond it. Whenever you need to merge configuration objects, webpack-merge can come in handy.
merge(...configuration | [...configuration])
merge
is the core, and the most important idea, of the API. Often this is all you need unless you want further customization.
const { merge } = require('webpack-merge');
const output = merge(object1, object2, object3, ...);
const output = merge([object1, object2, object3]);
const output = merge(
{ fruit: "apple", color: "red" },
{ fruit: "strawberries" }
);
console.log(output);
Limitations
Note that Promise
s are not supported! If you want to return a configuration wrapped within a Promise
, merge
inside one. Example: Promise.resolve(merge({ ... }, { ... }))
.
The same goes for configuration level functions as in the example below:
webpack.config.js
const commonConfig = { ... };
const productionConfig = { ... };
const developmentConfig = { ... };
module.exports = env => {
switch(env) {
case 'development':
return merge(commonConfig, developmentConfig);
case 'production':
return merge(commonConfig, productionConfig);
default:
throw new Error('No matching configuration was found!');
}
}
You can choose the configuration you want by using webpack --env development
assuming you are using webpack-cli.
mergeWithCustomize({ customizeArray, customizeObject })(...configuration | [...configuration])
In case you need more flexibility, merge
behavior can be customized per field as below:
const { mergeWithCustomize } = require('webpack-merge');
const output = mergeWithCustomize(
{
customizeArray(a, b, key) {
if (key === 'extensions') {
return _.uniq([...a, ...b]);
}
return undefined;
},
customizeObject(a, b, key) {
if (key === 'module') {
return _.merge({}, a, b);
}
return undefined;
}
}
)(object1, object2, object3, ...);
For example, if the previous code was invoked with only object1
and object2
with object1
as:
{
foo1: ['object1'],
foo2: ['object1'],
bar1: { object1: {} },
bar2: { object1: {} },
}
and object2
as:
{
foo1: ['object2'],
foo2: ['object2'],
bar1: { object2: {} },
bar2: { object2: {} },
}
then customizeArray
will be invoked for each property of Array
type, i.e:
customizeArray(["object1"], ["object2"], "foo1");
customizeArray(["object1"], ["object2"], "foo2");
and customizeObject
will be invoked for each property of Object
type, i.e:
customizeObject({ object1: {} }, { object2: {} }, bar1);
customizeObject({ object1: {} }, { object2: {} }, bar2);
customizeArray
and customizeObject
customizeArray
and customizeObject
provide small strategies to for mergeWithCustomize
. They support append
, prepend
, replace
, and wildcards for field names.
const { mergeWithCustomize, customizeArray, customizeObject } = require('webpack-merge');
const output = mergeWithCustomize({
customizeArray: customizeArray({
'entry.*': 'prepend'
}),
customizeObject: customizeObject({
entry: 'prepend'
})
})(object1, object2, object3, ...);
unique(<field>, <fields>, field => field)
unique
is a strategy used for forcing uniqueness within configuration. It's most useful with plugins when you want to make sure there's only one in place.
The first <field>
is the config property to look through for duplicates.
<fields>
represents the values that should be unique when you run the field => field function on each duplicate.
const { mergeWithCustomize, unique } = require("webpack-merge");
const output = mergeWithCustomize({
customizeArray: unique(
"plugins",
["HotModuleReplacementPlugin"],
(plugin) => plugin.constructor && plugin.constructor.name
),
})(
{
plugins: [new webpack.HotModuleReplacementPlugin()],
},
{
plugins: [new webpack.HotModuleReplacementPlugin()],
}
);
Development
nvm use
npm i
npm run build -- --watch
in one terminalnpm t -- --watch
in another one
Before contributing, please open an issue where to discuss.
Further Information and Support
Check out SurviveJS - Webpack to dig deeper into webpack. The free book uses webpack-merge extensively and shows you how to compose your configuration to keep it maintainable.
I am also available as a consultant in case you require specific assistance. I can contribute particularly in terms of improving maintainability of the setup while speeding it up and pointing out better practices. In addition to improving developer productivity, the work has impact on the end users of the product in terms of reduced application size and loading times.
Contributors
Code Contributors
This project exists thanks to all the people who contribute. [Contribute].
Financial Contributors
Become a financial contributor and help us sustain our community. [Contribute]
Individuals
Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]
License
webpack-merge is available under MIT. See LICENSE for more details.