What is webpack-merge?
The webpack-merge package provides a utility to merge multiple webpack configurations. It is useful for composing different webpack configurations for development, production, or any other purpose. It simplifies the process of combining configurations by smartly merging loaders, plugins, and other specific structures within the webpack configuration objects.
What are webpack-merge's main functionalities?
Merging basic configurations
This feature allows for the merging of two basic webpack configurations into one. It is useful for separating common configuration from environment-specific configurations.
const { merge } = require('webpack-merge');
const commonConfig = { entry: './src/app.js' };
const productionConfig = { mode: 'production' };
const mergedConfig = merge(commonConfig, productionConfig);
Merging with rules
This demonstrates merging configurations that include module rules. webpack-merge smartly combines the loaders, allowing for a nuanced configuration that can differ between development and production environments.
const { merge } = require('webpack-merge');
const commonConfig = { module: { rules: [ { test: /\.css$/, use: ['style-loader'] } ] } };
const productionConfig = { module: { rules: [ { test: /\.css$/, use: ['css-loader'] } ] } };
const mergedConfig = merge(commonConfig, productionConfig);
Customizing merge behavior
This feature allows for customizing the merge behavior, such as prepending or appending elements in arrays instead of the default merging strategy. It's particularly useful for fine-tuning the order of plugins or loaders.
const { mergeWithCustomize, customizeArray } = require('webpack-merge');
const commonConfig = { plugins: ['CommonPlugin'] };
const productionConfig = { plugins: ['ProductionPlugin'] };
const mergedConfig = mergeWithCustomize({ customizeArray: customizeArray({ 'plugins': 'prepend' }) })(commonConfig, productionConfig);
Other packages similar to webpack-merge
deepmerge
deepmerge is a library that can deeply merge multiple objects into one. While it's not specific to webpack configurations, it can be used for a similar purpose. However, webpack-merge offers webpack-specific merging capabilities that deepmerge does not, such as smart merging of loaders and plugins.
lodash.merge
lodash.merge is a method from the Lodash library that provides a deep merge of objects. Similar to deepmerge, it can be used to merge webpack configurations but lacks the webpack-specific intelligence of webpack-merge, potentially requiring more manual configuration for complex webpack setups.
webpack-merge - Merge designed for Webpack
Normal merge function isn't that useful with webpack configuration as it will override object keys and arrays by default. It is more beneficial to concatenate arrays instead. This little helper achieves just that.
API
var output = merge(object1, object2, object3, ...);
var output = merge.smart(object1, object2, object3, ...);
Example
package.json
{
"scripts": {
"start": "webpack-dev-server",
"build": "webpack"
},
...
}
webpack.config.js
var path = require('path');
var merge = require('webpack-merge');
var TARGET = process.env.npm_lifecycle_event;
var common = {
entry: path.join(__dirname, 'app'),
...
module: {
loaders: [
{
test: /\.css$/,
loaders: ['style', 'css'],
},
],
},
};
if(TARGET === 'start') {
module.exports = merge(common, {
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel?stage=1',
include: path.join(ROOT_PATH, 'app'),
},
],
},
...
});
}
if(TARGET === 'build') {
module.exports = merge(common, {
...
});
}
...
Check out SurviveJS - Webpack and React to dig deeper into the topic.
Smart Merging of Loaders
Webpack-merge tries to be smart about merging loaders when merge.smart
is used. Loaders with matching tests will be merged into a single loader value.
Loader string values loader: 'babel'
override each other.
merge.smart({
loaders: [{
test: /\.js$/,
loader: 'babel'
}]
}, {
loaders: [{
test: /\.js$/,
loader: 'coffee'
}]
});
{
loaders: [{
test: /\.js$/,
loader: 'coffee'
}]
}
Loader array values loaders: ['babel']
will be merged, without duplication.
merge.smart({
loaders: [{
test: /\.js$/,
loaders: ['babel']
}]
}, {
loaders: [{
test: /\.js$/,
loaders: ['coffee']
}]
});
{
loaders: [{
test: /\.js$/,
loaders: ['coffee', 'babel']
}]
}
Loader query strings loaders: ['babel?plugins[]=object-assign']
will be overridden
merge.smart({
loaders: [{
test: /\.js$/,
loaders: ['babel?plugins[]=object-assign']
}]
}, {
loaders: [{
test: /\.js$/,
loaders: ['babel', 'coffee']
}]
});
{
loaders: [{
test: /\.js$/,
loaders: ['babel', 'coffee']
}]
}
Loader arrays in source values will have loader strings merged into them.
merge.smart({
loaders: [{
test: /\.js$/,
loader: 'babel'
}]
}, {
loaders: [{
test: /\.js$/,
loaders: ['coffee']
}]
});
{
loaders: [{
test: /\.js$/,
loaders: ['coffee', 'babel']
}]
}
Loader strings in source values will always override.
merge.smart({
loaders: [{
test: /\.js$/,
loaders: ['babel']
}]
}, {
loaders: [{
test: /\.js$/,
loader: 'coffee'
}]
});
{
loaders: [{
test: /\.js$/,
loader: 'coffee'
}]
}
Contributors
License
webpack-merge is available under MIT. See LICENSE for more details.