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.
var output = merge(object1, object2, object3, ...);
// smarter merging for loaders, see below
var output = merge.smart(object1, object2, object3, ...);
Check out SurviveJS - Webpack and React to dig deeper into the topic.
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 will get concatenated!
loaders: [
{
test: /\.jsx?$/,
loader: 'babel?stage=1',
include: path.join(ROOT_PATH, 'app'),
},
],
},
...
});
}
if(TARGET === 'build') {
module.exports = merge(common, {
...
});
}
...
Note that you can override existing arrays/objects like this:
var common = {
entry: [APP_PATH, STYLE_PATH]
...
};
if(TARGET === 'test') {
module.exports = merge(common, {
entry: [], // empty now
...
});
}
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'
}]
});
// will become
{
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']
}]
});
// will become
{
loaders: [{
test: /\.js$/,
// prepended because Webpack evaluated these from right to left!
// this way you can specialize behavior and build the loader chain
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']
}]
});
// will become
{
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']
}]
});
// will become
{
loaders: [{
test: /\.js$/,
// prepended because Webpack evaluated these from right to left!
loaders: ['coffee', 'babel']
}]
}
Loader strings in source values will always override.
merge.smart({
loaders: [{
test: /\.js$/,
loaders: ['babel']
}]
}, {
loaders: [{
test: /\.js$/,
loader: 'coffee'
}]
});
// will become
{
loaders: [{
test: /\.js$/,
loader: 'coffee'
}]
}
- Fernando Montoya - Use separate lodash functions instead of the core package. Faster to install this way.
- Jonathan Felchlin - Smart merging for loaders.
- David Gómez - Performance and cosmetic improvements.
- siready - Extend
merge.smart
to supportinclude/exclude
. - C.J. Winslow - Make
merge.smart
include/exclude
to work correctly withloader
. - Artem Zakharchenko - Fix
merge.smart
duplication so that ifinclude
exists, it will merge.
webpack-merge is available under MIT. See LICENSE for more details.