Installations
npm install webpack-merge
Developer Guide
Typescript
❌ No
Module System
CommonJS
Min. Node Version
>=18.0.0
Node Version
22.3.0
NPM Version
10.8.1
Score
98.9
Supply Chain
100
Quality
77.5
Maintenance
100
Vulnerability
100
License
Releases
Unable to fetch releases
Developer
Statistics
Updated on 23 Nov 2024
Languages
TypeScript (99.91%)
JavaScript (0.09%)
Total Downloads
Cumulative downloads
Total Downloads
2,381,837,5962,381,837,596
Last day
17.5%
Compared to previous day
Last week
-2.7%
Compared to previous week
Last month
9.3%
Compared to previous month
Last year
7.4%
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
3
Dev Dependencies
8
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.
1const { merge } = require('webpack-merge'); 2 3// Default API 4const output = merge(object1, object2, object3, ...); 5 6// You can pass an array of objects directly. 7// This works with all available functions. 8const output = merge([object1, object2, object3]); 9 10// Keys matching to the right take precedence: 11const output = merge( 12 { fruit: "apple", color: "red" }, 13 { fruit: "strawberries" } 14); 15console.log(output); 16// { color: "red", fruit: "strawberries"}
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
1const commonConfig = { ... }; 2 3const productionConfig = { ... }; 4 5const developmentConfig = { ... }; 6 7module.exports = (env, args) => { 8 switch(args.mode) { 9 case 'development': 10 return merge(commonConfig, developmentConfig); 11 case 'production': 12 return merge(commonConfig, productionConfig); 13 default: 14 throw new Error('No matching configuration was found!'); 15 } 16}
You can choose the configuration you want by using webpack --mode 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:
1const { mergeWithCustomize } = require('webpack-merge'); 2 3const output = mergeWithCustomize( 4 { 5 customizeArray(a, b, key) { 6 if (key === 'extensions') { 7 return _.uniq([...a, ...b]); 8 } 9 10 // Fall back to default merging 11 return undefined; 12 }, 13 customizeObject(a, b, key) { 14 if (key === 'module') { 15 // Custom merging 16 return _.merge({}, a, b); 17 } 18 19 // Fall back to default merging 20 return undefined; 21 } 22 } 23)(object1, object2, object3, ...);
For example, if the previous code was invoked with only object1
and object2
with object1
as:
1{ 2 foo1: ['object1'], 3 foo2: ['object1'], 4 bar1: { object1: {} }, 5 bar2: { object1: {} }, 6}
and object2
as:
1{ 2 foo1: ['object2'], 3 foo2: ['object2'], 4 bar1: { object2: {} }, 5 bar2: { object2: {} }, 6}
then customizeArray
will be invoked for each property of Array
type, i.e:
1customizeArray(["object1"], ["object2"], "foo1"); 2customizeArray(["object1"], ["object2"], "foo2");
and customizeObject
will be invoked for each property of Object
type, i.e:
1customizeObject({ object1: {} }, { object2: {} }, bar1); 2customizeObject({ 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.
1const { mergeWithCustomize, customizeArray, customizeObject } = require('webpack-merge'); 2 3const output = mergeWithCustomize({ 4 customizeArray: customizeArray({ 5 'entry.*': 'prepend' 6 }), 7 customizeObject: customizeObject({ 8 entry: 'prepend' 9 }) 10})(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.
When the order of elements of the <field>
in the first configuration differs from the order in the second configuration, the latter is preserved.
1const { mergeWithCustomize, unique } = require("webpack-merge"); 2 3const output = mergeWithCustomize({ 4 customizeArray: unique( 5 "plugins", 6 ["HotModuleReplacementPlugin"], 7 (plugin) => plugin.constructor && plugin.constructor.name, 8 ), 9})( 10 { 11 plugins: [new webpack.HotModuleReplacementPlugin()], 12 }, 13 { 14 plugins: [new webpack.HotModuleReplacementPlugin()], 15 }, 16); 17 18// Output contains only single HotModuleReplacementPlugin now and it's 19// going to be the last plugin instance.
mergeWithRules
To support advanced merging needs (i.e. merging within loaders), mergeWithRules
includes additional syntax that allows you to match fields and apply strategies to match. Consider the full example below:
1const a = { 2 module: { 3 rules: [ 4 { 5 test: /\.css$/, 6 use: [{ loader: "style-loader" }, { loader: "sass-loader" }], 7 }, 8 ], 9 }, 10}; 11const b = { 12 module: { 13 rules: [ 14 { 15 test: /\.css$/, 16 use: [ 17 { 18 loader: "style-loader", 19 options: { 20 modules: true, 21 }, 22 }, 23 ], 24 }, 25 ], 26 }, 27}; 28const result = { 29 module: { 30 rules: [ 31 { 32 test: /\.css$/, 33 use: [ 34 { 35 loader: "style-loader", 36 options: { 37 modules: true, 38 }, 39 }, 40 { loader: "sass-loader" }, 41 ], 42 }, 43 ], 44 }, 45}; 46 47assert.deepStrictEqual( 48 mergeWithRules({ 49 module: { 50 rules: { 51 test: "match", 52 use: { 53 loader: "match", 54 options: "replace", 55 }, 56 }, 57 }, 58 })(a, b), 59 result, 60);
The way it works is that you should annotate fields to match using match
(or CustomizeRule.Match
if you are using TypeScript) matching your configuration structure and then use specific strategies to define how particular fields should be transformed. If a match doesn't exist above a rule, then it will apply the rule automatically.
Supported annotations:
match
(CustomizeRule.Match
) - Optional matcher that scopes merging behavior to a specific part based on similarity (think DOM or jQuery selectors)append
(CustomizeRule.Append
) - Appends itemsprepend
(CustomizeRule.Prepend
) - Prepends itemsreplace
(CustomizeRule.Replace
) - Replaces itemsmerge
(CustomizeRule.Merge
) - Merges objects (shallow merge)
Using with TypeScript
webpack-merge supports TypeScript out of the box. You should pass Configuration
type from webpack to it as follows:
1import { Configuration } from "webpack"; 2import { merge } from "webpack-merge"; 3 4const config = merge<Configuration>({...}, {...}); 5 6...
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 5 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.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
security policy file detected
Details
- Info: security policy file detected: SECURITY.md:1
- Info: Found linked content: SECURITY.md:1
- Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1
- Info: Found text in security policy: SECURITY.md:1
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
dependency not pinned by hash detected -- score normalized to 4
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/survivejs/webpack-merge/test.yml/develop?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/survivejs/webpack-merge/test.yml/develop?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/survivejs/webpack-merge/test.yml/develop?enable=pin
- Info: 0 out of 2 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 1 third-party GitHubAction dependencies pinned
- Info: 1 out of 1 npmCommand dependencies pinned
Reason
6 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
Reason
Found 4/26 approved changesets -- score normalized to 1
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/test.yml:1
- Info: no jobLevel write permissions found
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'develop'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 8 are checked with a SAST tool
Score
3.8
/10
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to webpack-merge
@types/webpack-merge
TypeScript definitions for webpack-merge
merge-jsons-webpack-plugin
This plugin is used to merge json files into single json file,using glob or file names
webpack-merge-and-include-globally
Merge multiple files (js,css..) into single file to include somewhere
antd-pro-merge-less
A webpack plugin for ant design pro less