JSPM

  • Created
  • Published
  • Downloads 18025138
  • Score
    100M100P100Q220281F
  • License MIT

Variant of merge that's useful for Webpack configuration

Package Exports

  • webpack-merge

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (webpack-merge) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

build status

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.

There's also a webpack specific merge variant known as merge.smart that's able to take webpack specifics into account (i.e., it can flatten loader definitions).

API

// Default API
var output = merge(object1, object2, object3, ...);

// You can pass an array of objects directly.
// This works with all available functions.
var output = merge([object1, object2, object3]);

// Customizing array/object behavior
var output = merge({
  customizeArray(a, b, key) { return [...a, ...b]; },
  customizeObject(a, b, key) { return mergeWith(a, b); }
})(object1, object2, object3, ...);

// Smarter merging for loaders, see below
var output = merge.smart(object1, object2, object3, ...);

// Merging with a specific merge strategy
var output = merge.strategy({
  entry: 'prepend', // or 'replace'
  'module.loaders': 'prepend'
})(object1, object2, object3, ...);

// The same idea works with smart merging too
var output = merge.smartStrategy({
  entry: 'prepend', // or 'replace'
  'module.loaders': 'prepend'
})(object1, object2, object3, ...);

Check out SurviveJS - Webpack and React to dig deeper into the topic.

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 will get concatenated!
      loaders: [
        {
          test: /\.jsx?$/,
          loader: 'babel?stage=1',
          include: path.join(ROOT_PATH, 'app'),
        },
      ],
    },
    ...
  });
}

if(TARGET === 'build') {
  module.exports = merge(common, {
    ...
  });
}

...

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.

Note that the logic picks up webpack 2 rules kind of syntax as well. The examples below have been written in webpack 1 syntax.

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$/,
    // appended because Webpack evaluated these from right to left
    // this way you can specialize behavior and build the loader chain
    loaders: ['babel', 'coffee']
  }]
}

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$/,
    // appended because Webpack evaluated these from right to left!
    loaders: ['babel', 'coffee']
  }]
}

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'
  }]
}

Development

  1. npm i
  2. npm run watch

Before contributing, please open an issue where to discuss.

License

webpack-merge is available under MIT. See LICENSE for more details.