source: trip-planner-front/node_modules/webpack-merge/README.md@ 76712b2

Last change on this file since 76712b2 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 10.8 KB
RevLine 
[6a3a178]1[![Financial Contributors on Open Collective](https://opencollective.com/webpack-merge/all/badge.svg?label=financial+contributors)](https://opencollective.com/webpack-merge) [![build status](https://secure.travis-ci.org/survivejs/webpack-merge.svg)](http://travis-ci.org/survivejs/webpack-merge) [![codecov](https://codecov.io/gh/survivejs/webpack-merge/branch/master/graph/badge.svg)](https://codecov.io/gh/survivejs/webpack-merge)
2
3# webpack-merge - Merge designed for Webpack
4
5**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.
6
7This 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.
8
9## **`merge(...configuration | [...configuration])`**
10
11`merge` is the core, and the most important idea, of the API. Often this is all you need unless you want further customization.
12
13```javascript
14const { merge } = require('webpack-merge');
15
16// Default API
17const output = merge(object1, object2, object3, ...);
18
19// You can pass an array of objects directly.
20// This works with all available functions.
21const output = merge([object1, object2, object3]);
22
23// Keys matching to the right take precedence:
24const output = merge(
25 { fruit: "apple", color: "red" },
26 { fruit: "strawberries" }
27);
28console.log(output);
29// { color: "red", fruit: "strawberries"}
30```
31
32### Limitations
33
34Note that `Promise`s are not supported! If you want to return a configuration wrapped within a `Promise`, `merge` inside one. Example: `Promise.resolve(merge({ ... }, { ... }))`.
35
36The same goes for configuration level functions as in the example below:
37
38**webpack.config.js**
39
40```javascript
41const commonConfig = { ... };
42
43const productionConfig = { ... };
44
45const developmentConfig = { ... };
46
47module.exports = (env, args) => {
48 switch(args.mode) {
49 case 'development':
50 return merge(commonConfig, developmentConfig);
51 case 'production':
52 return merge(commonConfig, productionConfig);
53 default:
54 throw new Error('No matching configuration was found!');
55 }
56}
57```
58
59You can choose the configuration you want by using `webpack --mode development` assuming you are using _webpack-cli_.
60
61## **`mergeWithCustomize({ customizeArray, customizeObject })(...configuration | [...configuration])`**
62
63In case you need more flexibility, `merge` behavior can be customized per field as below:
64
65```javascript
66const { mergeWithCustomize } = require('webpack-merge');
67
68const output = mergeWithCustomize(
69 {
70 customizeArray(a, b, key) {
71 if (key === 'extensions') {
72 return _.uniq([...a, ...b]);
73 }
74
75 // Fall back to default merging
76 return undefined;
77 },
78 customizeObject(a, b, key) {
79 if (key === 'module') {
80 // Custom merging
81 return _.merge({}, a, b);
82 }
83
84 // Fall back to default merging
85 return undefined;
86 }
87 }
88)(object1, object2, object3, ...);
89```
90
91For example, if the previous code was invoked with only `object1` and `object2`
92with `object1` as:
93
94```javascript
95{
96 foo1: ['object1'],
97 foo2: ['object1'],
98 bar1: { object1: {} },
99 bar2: { object1: {} },
100}
101```
102
103and `object2` as:
104
105```javascript
106{
107 foo1: ['object2'],
108 foo2: ['object2'],
109 bar1: { object2: {} },
110 bar2: { object2: {} },
111}
112```
113
114then `customizeArray` will be invoked for each property of `Array` type, i.e:
115
116```javascript
117customizeArray(["object1"], ["object2"], "foo1");
118customizeArray(["object1"], ["object2"], "foo2");
119```
120
121and `customizeObject` will be invoked for each property of `Object` type, i.e:
122
123```javascript
124customizeObject({ object1: {} }, { object2: {} }, bar1);
125customizeObject({ object1: {} }, { object2: {} }, bar2);
126```
127
128## **`customizeArray`** and **`customizeObject`**
129
130`customizeArray` and `customizeObject` provide small strategies to for `mergeWithCustomize`. They support `append`, `prepend`, `replace`, and wildcards for field names.
131
132```javascript
133const { mergeWithCustomize, customizeArray, customizeObject } = require('webpack-merge');
134
135const output = mergeWithCustomize({
136 customizeArray: customizeArray({
137 'entry.*': 'prepend'
138 }),
139 customizeObject: customizeObject({
140 entry: 'prepend'
141 })
142})(object1, object2, object3, ...);
143```
144
145## **`unique(<field>, <fields>, field => field)`**
146
147`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.
148
149The first `<field>` is the config property to look through for duplicates.
150
151`<fields>` represents the values that should be unique when you run the field => field function on each duplicate.
152
153When the order of elements of the `<field>` in the first configuration differs from the order in the second configuration, the latter is preserved.
154
155```javascript
156const { mergeWithCustomize, unique } = require("webpack-merge");
157
158const output = mergeWithCustomize({
159 customizeArray: unique(
160 "plugins",
161 ["HotModuleReplacementPlugin"],
162 (plugin) => plugin.constructor && plugin.constructor.name
163 ),
164})(
165 {
166 plugins: [new webpack.HotModuleReplacementPlugin()],
167 },
168 {
169 plugins: [new webpack.HotModuleReplacementPlugin()],
170 }
171);
172
173// Output contains only single HotModuleReplacementPlugin now and it's
174// going to be the last plugin instance.
175```
176
177## **`mergeWithRules`**
178
179To 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:
180
181```javascript
182const a = {
183 module: {
184 rules: [
185 {
186 test: /\.css$/,
187 use: [{ loader: "style-loader" }, { loader: "sass-loader" }],
188 },
189 ],
190 },
191};
192const b = {
193 module: {
194 rules: [
195 {
196 test: /\.css$/,
197 use: [
198 {
199 loader: "style-loader",
200 options: {
201 modules: true,
202 },
203 },
204 ],
205 },
206 ],
207 },
208};
209const result = {
210 module: {
211 rules: [
212 {
213 test: /\.css$/,
214 use: [
215 {
216 loader: "style-loader",
217 options: {
218 modules: true,
219 },
220 },
221 { loader: "sass-loader" },
222 ],
223 },
224 ],
225 },
226};
227
228assert.deepStrictEqual(
229 mergeWithRules({
230 module: {
231 rules: {
232 test: "match",
233 use: {
234 loader: "match",
235 options: "replace",
236 },
237 },
238 },
239 })(a, b),
240 result
241);
242```
243
244The 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.
245
246**Supported annotations:**
247
248- `match` (`CustomizeRule.Match`) - Optional matcher that scopes merging behavior to a specific part based on similarity (think DOM or jQuery selectors)
249- `append` (`CustomizeRule.Append`) - Appends items
250- `prepend` (`CustomizeRule.Prepend`) - Prepends items
251- `replace` (`CustomizeRule.Replace`) - Replaces items
252- `merge` (`CustomizeRule.Merge`) - Merges objects (shallow merge)
253
254## Using with TypeScript
255
256**webpack-merge** supports TypeScript out of the box. You should pass `Configuration` type from webpack to it as follows:
257
258```typescript
259import { Configuration } from "webpack";
260import { merge } from "webpack-merge";
261
262const config = merge<Configuration>({...}, {...});
263
264...
265```
266
267## Development
268
2691. `nvm use`
2701. `npm i`
2711. `npm run build -- --watch` in one terminal
2721. `npm t -- --watch` in another one
273
274Before contributing, please [open an issue](https://github.com/survivejs/webpack-merge/issues/new) where to discuss.
275
276## Further Information and Support
277
278Check out [SurviveJS - Webpack 5](http://survivejs.com/) to dig deeper into webpack. The free book uses **webpack-merge** extensively and shows you how to compose your configuration to keep it maintainable.
279
280I 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.
281
282## Contributors
283
284### Code Contributors
285
286This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
287<a href="https://github.com/survivejs/webpack-merge/graphs/contributors"><img src="https://opencollective.com/webpack-merge/contributors.svg?width=890&button=false" /></a>
288
289### Financial Contributors
290
291Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/webpack-merge/contribute)]
292
293#### Individuals
294
295<a href="https://opencollective.com/webpack-merge"><img src="https://opencollective.com/webpack-merge/individuals.svg?width=890"></a>
296
297#### Organizations
298
299Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/webpack-merge/contribute)]
300
301<a href="https://opencollective.com/webpack-merge/organization/0/website"><img src="https://opencollective.com/webpack-merge/organization/0/avatar.svg"></a>
302<a href="https://opencollective.com/webpack-merge/organization/1/website"><img src="https://opencollective.com/webpack-merge/organization/1/avatar.svg"></a>
303<a href="https://opencollective.com/webpack-merge/organization/2/website"><img src="https://opencollective.com/webpack-merge/organization/2/avatar.svg"></a>
304<a href="https://opencollective.com/webpack-merge/organization/3/website"><img src="https://opencollective.com/webpack-merge/organization/3/avatar.svg"></a>
305<a href="https://opencollective.com/webpack-merge/organization/4/website"><img src="https://opencollective.com/webpack-merge/organization/4/avatar.svg"></a>
306<a href="https://opencollective.com/webpack-merge/organization/5/website"><img src="https://opencollective.com/webpack-merge/organization/5/avatar.svg"></a>
307<a href="https://opencollective.com/webpack-merge/organization/6/website"><img src="https://opencollective.com/webpack-merge/organization/6/avatar.svg"></a>
308<a href="https://opencollective.com/webpack-merge/organization/7/website"><img src="https://opencollective.com/webpack-merge/organization/7/avatar.svg"></a>
309<a href="https://opencollective.com/webpack-merge/organization/8/website"><img src="https://opencollective.com/webpack-merge/organization/8/avatar.svg"></a>
310<a href="https://opencollective.com/webpack-merge/organization/9/website"><img src="https://opencollective.com/webpack-merge/organization/9/avatar.svg"></a>
311
312## License
313
314**webpack-merge** is available under MIT. See LICENSE for more details.
Note: See TracBrowser for help on using the repository browser.