From 57ec2957ecfab174a9dad07c41cfcf476d64baa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Thu, 12 Nov 2020 10:59:51 +0100 Subject: [PATCH 01/12] chore: Apply prettier 2 --- CHANGELOG.md | 20 +- README.md | 52 ++--- helpers/customize-tests.ts | 118 +++++------ helpers/merge-multiple-tests.ts | 118 +++++------ helpers/merge-tests.ts | 162 +++++++------- package-lock.json | 12 +- package.json | 1 + src/index.ts | 20 +- src/join-arrays.ts | 4 +- src/merge-with.ts | 4 +- src/types.ts | 2 +- test/customize.test.ts | 54 ++--- test/merge-with-customize.test.ts | 62 +++--- test/merge-with-rules.test.ts | 342 +++++++++++++++--------------- test/merge.test.ts | 231 ++++++++++---------- test/unique.test.ts | 70 +++--- 16 files changed, 641 insertions(+), 631 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f40d9ad..150ba16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -118,17 +118,17 @@ merge.smart( loaders: [ { test: /\.js$/, - loaders: ["babel"] - } - ] + loaders: ["babel"], + }, + ], }, { loaders: [ { test: /\.js$/, - loaders: ["react-hot", "babel"] - } - ] + loaders: ["react-hot", "babel"], + }, + ], } ); // will become @@ -137,8 +137,8 @@ merge.smart( { test: /\.js$/, // order of second argument is respected - loaders: ["react-hot", "babel"] - } + loaders: ["react-hot", "babel"], + }, ]; } ``` @@ -199,10 +199,10 @@ const output = merge.smartStrategy( ```javascript const a = { - entry: ["foo"] + entry: ["foo"], }; const b = { - entry: [] + entry: [], }; merge(a, b); // Yields a result, not b like before. diff --git a/README.md b/README.md index f5ad9ec..71b7f5f 100644 --- a/README.md +++ b/README.md @@ -157,14 +157,14 @@ const output = mergeWithCustomize({ customizeArray: unique( "plugins", ["HotModuleReplacementPlugin"], - plugin => plugin.constructor && plugin.constructor.name - ) + (plugin) => plugin.constructor && plugin.constructor.name + ), })( { - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [new webpack.HotModuleReplacementPlugin()], }, { - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [new webpack.HotModuleReplacementPlugin()], } ); @@ -182,10 +182,10 @@ const a = { rules: [ { test: /\.css$/, - use: [{ loader: "style-loader" }, { loader: "sass-loader" }] - } - ] - } + use: [{ loader: "style-loader" }, { loader: "sass-loader" }], + }, + ], + }, }; const b = { module: { @@ -196,13 +196,13 @@ const b = { { loader: "style-loader", options: { - modules: true - } - } - ] - } - ] - } + modules: true, + }, + }, + ], + }, + ], + }, }; const result = { module: { @@ -213,14 +213,14 @@ const result = { { loader: "style-loader", options: { - modules: true - } + modules: true, + }, }, - { loader: "sass-loader" } - ] - } - ] - } + { loader: "sass-loader" }, + ], + }, + ], + }, }; assert.deepStrictEqual( @@ -230,10 +230,10 @@ assert.deepStrictEqual( test: "match", use: { loader: "match", - options: "replace" - } - } - } + options: "replace", + }, + }, + }, })(a, b), result ); diff --git a/helpers/customize-tests.ts b/helpers/customize-tests.ts index 23f3d88..226ffa1 100644 --- a/helpers/customize-tests.ts +++ b/helpers/customize-tests.ts @@ -1,240 +1,240 @@ import assert from "assert"; function mergeStrategyTests(merge) { - it("should allow setting to array append", function() { + it("should allow setting to array append", function () { const a = { - entry: ["foo", "bar", "baz"] + entry: ["foo", "bar", "baz"], }; const b = { - entry: ["zoo"] + entry: ["zoo"], }; const result = { - entry: ["foo", "bar", "baz", "zoo"] + entry: ["foo", "bar", "baz", "zoo"], }; assert.deepStrictEqual( merge({ - entry: "append" + entry: "append", })(a, b), result ); }); - it("should allow setting to array prepend", function() { + it("should allow setting to array prepend", function () { const a = { - entry: ["foo", "bar", "baz"] + entry: ["foo", "bar", "baz"], }; const b = { - entry: ["zoo"] + entry: ["zoo"], }; const result = { - entry: ["zoo", "foo", "bar", "baz"] + entry: ["zoo", "foo", "bar", "baz"], }; assert.deepStrictEqual( merge({ - entry: "prepend" + entry: "prepend", })(a, b), result ); }); - it("should allow setting to object append", function() { + it("should allow setting to object append", function () { const a = { entry: { - foo: "bar" - } + foo: "bar", + }, }; const b = { entry: { - bar: "baz" - } + bar: "baz", + }, }; const result = { entry: { foo: "bar", - bar: "baz" - } + bar: "baz", + }, }; assert.deepStrictEqual( Object.keys( merge({ - entry: "append" + entry: "append", })(a, b).entry ), Object.keys(result.entry) ); }); - it("should allow setting to object prepend", function() { + it("should allow setting to object prepend", function () { const a = { entry: { - foo: "bar" - } + foo: "bar", + }, }; const b = { entry: { - bar: "baz" - } + bar: "baz", + }, }; const result = { entry: { bar: "baz", - foo: "bar" - } + foo: "bar", + }, }; assert.deepStrictEqual( Object.keys( merge({ - entry: "prepend" + entry: "prepend", })(a, b).entry ), Object.keys(result.entry) ); }); - it("should allow replace strategy for arrays", function() { + it("should allow replace strategy for arrays", function () { const a = { - entry: ["foo"] + entry: ["foo"], }; const b = { - entry: ["bar"] + entry: ["bar"], }; const result = { - entry: ["bar"] + entry: ["bar"], }; assert.deepStrictEqual( Object.keys( merge({ - entry: "replace" + entry: "replace", })(a, b).entry ), Object.keys(result.entry) ); }); - it("should allow replace strategy for objects", function() { + it("should allow replace strategy for objects", function () { const a = { entry: { - foo: "bar" - } + foo: "bar", + }, }; const b = { entry: { - bar: "baz" - } + bar: "baz", + }, }; const result = { entry: { - bar: "baz" - } + bar: "baz", + }, }; assert.deepStrictEqual( Object.keys( merge({ - entry: "replace" + entry: "replace", })(a, b).entry ), Object.keys(result.entry) ); }); - it("should merge functions returning arrays with prepend", function() { + it("should merge functions returning arrays with prepend", function () { const a = { postcss() { return ["a"]; - } + }, }; const b = { postcss() { return ["b"]; - } + }, }; const expected = ["b", "a"]; assert.deepStrictEqual( merge({ - postcss: "prepend" + postcss: "prepend", })(a, b).postcss(), expected ); }); - it("should merge functions returning objects with prepend", function() { + it("should merge functions returning objects with prepend", function () { const a = { postcss() { return { - a: "foo" + a: "foo", }; - } + }, }; const b = { postcss() { return { - b: "bar" + b: "bar", }; - } + }, }; const result = { postcss() { return { b: "bar", - a: "foo" + a: "foo", }; - } + }, }; assert.deepStrictEqual( Object.keys( merge({ - postcss: "prepend" + postcss: "prepend", })(a, b).postcss() ), Object.keys(result.postcss()) ); }); - it("should merge functions returning arrays with replace", function() { + it("should merge functions returning arrays with replace", function () { const a = { postcss() { return ["a"]; - } + }, }; const b = { postcss() { return ["b"]; - } + }, }; const expected = ["b"]; assert.deepStrictEqual( merge({ - postcss: "replace" + postcss: "replace", })(a, b).postcss(), expected ); }); - it("should merge functions returning objects with replace", function() { + it("should merge functions returning objects with replace", function () { const a = { postcss() { return ["a"]; - } + }, }; const b = { postcss() { return ["b"]; - } + }, }; const expected = ["b"]; assert.deepStrictEqual( merge({ - postcss: "replace" + postcss: "replace", })(a, b).postcss(), expected ); diff --git a/helpers/merge-multiple-tests.ts b/helpers/merge-multiple-tests.ts index 32952b6..36f9c42 100644 --- a/helpers/merge-multiple-tests.ts +++ b/helpers/merge-multiple-tests.ts @@ -1,88 +1,88 @@ import assert from "assert"; function multipleTests(merge) { - it("should override objects", function() { + it("should override objects", function () { const a = { client: { - entry: "./client.js" - } + entry: "./client.js", + }, }; const b = { client: { - entry: "./replaced.js" - } + entry: "./replaced.js", + }, }; const result = [ { - entry: "./replaced.js" - } + entry: "./replaced.js", + }, ]; assert.deepStrictEqual(merge(a, b), result); }); - it("should add new objects if not existing", function() { + it("should add new objects if not existing", function () { const a = { client: { - entry: "./client.js" + entry: "./client.js", }, server: { - entry: "./server.js" - } + entry: "./server.js", + }, }; const b = { client: { - entry: "./replaced.js" - } + entry: "./replaced.js", + }, }; const result = [ { - entry: "./replaced.js" + entry: "./replaced.js", }, { - entry: "./server.js" - } + entry: "./server.js", + }, ]; assert.deepStrictEqual(merge(a, b), result); }); - it("should add different configurations without merging", function() { + it("should add different configurations without merging", function () { const a = { client: { - entry: "./client.js" - } + entry: "./client.js", + }, }; const b = { server: { - entry: "./server.js" - } + entry: "./server.js", + }, }; const result = [ { - entry: "./client.js" + entry: "./client.js", }, { - entry: "./server.js" - } + entry: "./server.js", + }, ]; assert.deepStrictEqual(merge(a, b), result); }); - it("should work with an array of objects", function() { + it("should work with an array of objects", function () { const a = { client: { - entry: ["./client.js", "./client2.js"] + entry: ["./client.js", "./client2.js"], }, server: { - entry: ["./server.js", "./server2.js"] - } + entry: ["./server.js", "./server2.js"], + }, }; const b = { client: { - entry: ["./replaced.js", "./replaced2.js"] - } + entry: ["./replaced.js", "./replaced2.js"], + }, }; const result = [ { @@ -90,80 +90,80 @@ function multipleTests(merge) { "./client.js", "./client2.js", "./replaced.js", - "./replaced2.js" - ] + "./replaced2.js", + ], }, { - entry: ["./server.js", "./server2.js"] - } + entry: ["./server.js", "./server2.js"], + }, ]; assert.deepStrictEqual(merge(a, b), result); }); - it("should deeply merge objects", function() { + it("should deeply merge objects", function () { const a = { client: { entry: { - main: "./client.js" - } + main: "./client.js", + }, }, server: { entry: { - main: "./server.js" - } - } + main: "./server.js", + }, + }, }; const b = { client: { entry: { - main: "./replaced.js" - } - } + main: "./replaced.js", + }, + }, }; const result = [ { entry: { - main: "./replaced.js" - } + main: "./replaced.js", + }, }, { entry: { - main: "./server.js" - } - } + main: "./server.js", + }, + }, ]; assert.deepStrictEqual(merge(a, b), result); }); - it("should merge where keys exist and add where not", function() { + it("should merge where keys exist and add where not", function () { const a = { client: { - entry: "./client.js" + entry: "./client.js", }, server: { - entry: "./server.js" - } + entry: "./server.js", + }, }; const b = { server: { - entry: "./replaced.js" + entry: "./replaced.js", }, test: { - entry: "./test.js" - } + entry: "./test.js", + }, }; const result = [ { - entry: "./client.js" + entry: "./client.js", }, { - entry: "./replaced.js" + entry: "./replaced.js", }, { - entry: "./test.js" - } + entry: "./test.js", + }, ]; assert.deepStrictEqual(merge(a, b), result); diff --git a/helpers/merge-tests.ts b/helpers/merge-tests.ts index 36560ff..a0cc94f 100644 --- a/helpers/merge-tests.ts +++ b/helpers/merge-tests.ts @@ -2,89 +2,89 @@ import assert from "assert"; import webpack from "webpack"; function mergeTests(merge) { - it("should return the same config", function() { + it("should return the same config", function () { const config = { entry: { - app: "app" + app: "app", }, output: { path: "build", - filename: "[name].js" + filename: "[name].js", }, - plugins: [] + plugins: [], }; assert.deepStrictEqual(merge(config), config); }); - it("should append arrays of multiple objects by default", function() { + it("should append arrays of multiple objects by default", function () { const a = { - foo: ["a"] + foo: ["a"], }; const b = { - foo: ["b"] + foo: ["b"], }; const c = { - foo: ["c"] + foo: ["c"], }; const result = { - foo: ["a", "b", "c"] + foo: ["a", "b", "c"], }; assert.deepStrictEqual(merge(a, b, c), result); }); - it("should work with an array of objects", function() { + it("should work with an array of objects", function () { const a = { - foo: ["a"] + foo: ["a"], }; const b = { - foo: ["b"] + foo: ["b"], }; const c = { - foo: ["c"] + foo: ["c"], }; const result = { - foo: ["a", "b", "c"] + foo: ["a", "b", "c"], }; assert.deepStrictEqual(merge([a, b, c]), result); }); - it("should override objects", function() { + it("should override objects", function () { const a = { - foo: "a" + foo: "a", }; const result = { - foo: "b" + foo: "b", }; assert.deepStrictEqual(merge(a, result), result); }); - it("should append arrays by default", function() { + it("should append arrays by default", function () { const a = { - foo: ["a"] + foo: ["a"], }; const b = { - foo: ["b"] + foo: ["b"], }; const result = { - foo: ["a", "b"] + foo: ["a", "b"], }; assert.deepStrictEqual(merge(a, b), result); }); - it("should append arrays without mutating", function() { + it("should append arrays without mutating", function () { const a = { - foo: ["a"] + foo: ["a"], }; const b = { - foo: ["b"] + foo: ["b"], }; const result = { - foo: ["a", "b"] + foo: ["a", "b"], }; // this should not mutate @@ -93,80 +93,80 @@ function mergeTests(merge) { assert.deepStrictEqual(merge(a, b), result); }); - it("should override objects of multiple objects", function() { + it("should override objects of multiple objects", function () { const a = { - foo: "a" + foo: "a", }; const b = { - foo: "b" + foo: "b", }; const result = { - foo: "c" + foo: "c", }; assert.deepStrictEqual(merge(a, b, result), result); }); - it("should deeply merge objects", function() { + it("should deeply merge objects", function () { const a = { - foo: { bar: "a" } + foo: { bar: "a" }, }; const b = { - foo: { baz: "b" } + foo: { baz: "b" }, }; const result = { foo: { bar: "a", - baz: "b" - } + baz: "b", + }, }; assert.deepStrictEqual(merge(a, b), result); }); - it("should not error when there are no matching loaders", function() { + it("should not error when there are no matching loaders", function () { const a = { loaders: [ { test: /\.js$/, - loader: "a" - } - ] + loader: "a", + }, + ], }; const b = { loaders: [ { test: /\.css$/, - loader: "b" - } - ] + loader: "b", + }, + ], }; const result = { loaders: [ { test: /\.js$/, - loader: "a" + loader: "a", }, { test: /\.css$/, - loader: "b" - } - ] + loader: "b", + }, + ], }; assert.deepStrictEqual(merge(a, b), result); }); - it("should not mutate inputs", function() { + it("should not mutate inputs", function () { const a = { output: { - filename: "bundle.js" - } + filename: "bundle.js", + }, }; const b = { output: { - path: "path/b" - } + path: "path/b", + }, }; const aClone = JSON.parse(JSON.stringify(a)); @@ -175,88 +175,88 @@ function mergeTests(merge) { assert.deepStrictEqual(a, aClone); }); - it("should not allow overriding with an empty array", function() { + it("should not allow overriding with an empty array", function () { const a = { - entry: ["foo"] + entry: ["foo"], }; const b = { - entry: [] + entry: [], }; assert.deepStrictEqual(merge(a, b), a); }); - it("should not allow overriding with an empty object", function() { + it("should not allow overriding with an empty object", function () { const a = { entry: { - a: "foo" - } + a: "foo", + }, }; const b = { - entry: {} + entry: {}, }; assert.deepStrictEqual(merge(a, b), a); }); - it("should merge functions that return arrays", function() { + it("should merge functions that return arrays", function () { const a = { postcss() { return ["a"]; - } + }, }; const b = { postcss() { return ["b"]; - } + }, }; const expected = ["a", "b"]; assert.deepStrictEqual(merge(a, b).postcss(), expected); }); - it("should merge functions that return objects", function() { + it("should merge functions that return objects", function () { const a = { postcss() { return { - a: "foo" + a: "foo", }; - } + }, }; const b = { postcss() { return { - b: "bar" + b: "bar", }; - } + }, }; const expected = { a: "foo", - b: "bar" + b: "bar", }; assert.deepStrictEqual(merge(a, b).postcss(), expected); }); - it("should merge functions that take arguments", function() { + it("should merge functions that take arguments", function () { const a = { postcss(arg) { return [arg]; - } + }, }; const b = { postcss(arg) { return [arg + 1, arg + 2]; - } + }, }; const expected = ["a", "a1", "a2"]; assert.deepStrictEqual(merge(a, b).postcss("a"), expected); }); - it("should not mutate inputs with mismatched keys", function() { + it("should not mutate inputs with mismatched keys", function () { const a = { - entry: {} + entry: {}, }; const b = {}; @@ -269,34 +269,34 @@ function mergeTests(merge) { assert.deepStrictEqual(a, aClone); }); - it("should not mutate plugins #106", function() { + it("should not mutate plugins #106", function () { const config1 = { entry: { page1: "src/page1", - page2: "src/page2" + page2: "src/page2", }, output: { path: "dist", - publicPath: "/" - } + publicPath: "/", + }, }; const config2 = { entry: { page3: "src/page3", - page4: "src/page4" + page4: "src/page4", }, output: { path: "dist", - publicPath: "/" - } + publicPath: "/", + }, }; const enhance = { plugins: [ new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, - contextRegExp: /moment$/ - }) - ] + contextRegExp: /moment$/, + }), + ], }; const result1 = merge(config1, enhance); diff --git a/package-lock.json b/package-lock.json index eeb8420..ba60027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6841,9 +6841,9 @@ "dev": true }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", + "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", "dev": true }, "prettier-linter-helpers": { @@ -8752,6 +8752,12 @@ "typescript": "^3.7.3" }, "dependencies": { + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", diff --git a/package.json b/package.json index ed53fd5..fe2107f 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "devDependencies": { "@types/estree": "0.0.45", "husky": "^4.3.0", + "prettier": "^2.1.2", "tsdx": "^0.14.1", "tslib": "^2.0.3", "typescript": "^4.0.5", diff --git a/src/index.ts b/src/index.ts index 6987b07..424e93d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -71,7 +71,7 @@ function mergeWithCustomize( function customizeArray(rules: { [s: string]: CustomizeRule }) { return (a: any, b: any, key: Key) => { const matchedRule = - Object.keys(rules).find(rule => wildcard(rule, key)) || ""; + Object.keys(rules).find((rule) => wildcard(rule, key)) || ""; if (matchedRule) { switch (rules[matchedRule]) { @@ -94,7 +94,7 @@ function mergeWithRules(rules: Rules) { customizeArray: (a: any, b: any, key: Key) => { let currentRule: CustomizeRule | Rules = rules; - key.split(".").forEach(k => { + key.split(".").forEach((k) => { if (!currentRule) { return; } @@ -107,7 +107,7 @@ function mergeWithRules(rules: Rules) { } return undefined; - } + }, }); } @@ -116,7 +116,7 @@ const isArray = Array.isArray; function mergeWithRule({ currentRule, a, - b + b, }: { currentRule: CustomizeRule | Rules; a: any; @@ -127,7 +127,7 @@ function mergeWithRule({ } const bAllMatches: any[] = []; - const ret = a.map(ao => { + const ret = a.map((ao) => { if (!isPlainObject(currentRule)) { return ao; } @@ -143,9 +143,9 @@ function mergeWithRule({ } }); - const bMatches = b.filter(o => { + const bMatches = b.filter((o) => { const matches = rulesToMatch.every( - rule => ao[rule]?.toString() === o[rule]?.toString() + (rule) => ao[rule]?.toString() === o[rule]?.toString() ); if (matches) { @@ -189,7 +189,7 @@ function mergeWithRule({ // Use .flat(); starting from Node 12 const b = bMatches - .map(o => o[k]) + .map((o) => o[k]) .reduce( (acc, val) => isArray(acc) && isArray(val) ? [...acc, ...val] : acc, @@ -204,7 +204,7 @@ function mergeWithRule({ return ret; }); - return ret.concat(b.filter(o => !bAllMatches.includes(o))); + return ret.concat(b.filter((o) => !bAllMatches.includes(o))); } function last(arr) { @@ -233,5 +233,5 @@ export { merge as default, mergeWithCustomize, mergeWithRules, - unique + unique, }; diff --git a/src/join-arrays.ts b/src/join-arrays.ts index 26ab578..56dd0ea 100644 --- a/src/join-arrays.ts +++ b/src/join-arrays.ts @@ -8,7 +8,7 @@ const isArray = Array.isArray; export default function joinArrays({ customizeArray, customizeObject, - key + key, }: { customizeArray?: Customize; customizeObject?: Customize; @@ -41,7 +41,7 @@ export default function joinArrays({ joinArrays({ customizeArray, customizeObject, - key: newKey + key: newKey, }) ) ); diff --git a/src/merge-with.ts b/src/merge-with.ts index b6bead5..ce85075 100644 --- a/src/merge-with.ts +++ b/src/merge-with.ts @@ -2,7 +2,7 @@ function mergeWith(objects: object[], customizer) { const [first, ...rest] = objects; let ret = first; - rest.forEach(a => { + rest.forEach((a) => { ret = mergeTo(ret, a, customizer); }); @@ -14,7 +14,7 @@ function mergeTo(a, b, customizer) { Object.keys(a) .concat(Object.keys(b)) - .forEach(k => { + .forEach((k) => { const v = customizer(a[k], b[k], k); ret[k] = typeof v === "undefined" ? a[k] : v; diff --git a/src/types.ts b/src/types.ts index afb319c..f42b47b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,5 +11,5 @@ export enum CustomizeRule { Match = "match", Append = "append", Prepend = "prepend", - Replace = "replace" + Replace = "replace", } diff --git a/test/customize.test.ts b/test/customize.test.ts index a0fc364..cc89eca 100644 --- a/test/customize.test.ts +++ b/test/customize.test.ts @@ -2,16 +2,16 @@ import assert from "assert"; import { customizeArray, customizeObject, - mergeWithCustomize + mergeWithCustomize, } from "../resolve"; import customizeTests from "../helpers/customize-tests"; import { CustomizeRule } from "../src/types"; -describe("Merge strategy", function() { - const merge = rules => +describe("Merge strategy", function () { + const merge = (rules) => mergeWithCustomize({ customizeArray: customizeArray(rules), - customizeObject: customizeObject(rules) + customizeObject: customizeObject(rules), }); customizeTests(merge); @@ -19,17 +19,17 @@ describe("Merge strategy", function() { }); function mergeStrategySpecificTests(merge) { - it("should work with nested arrays and prepend", function() { + it("should work with nested arrays and prepend", function () { const a = { module: { loaders: [ { test: /.jsx?$/, loaders: ["babel"], - exclude: /node_modules/ - } - ] - } + exclude: /node_modules/, + }, + ], + }, }; const b = { module: { @@ -37,10 +37,10 @@ function mergeStrategySpecificTests(merge) { { test: /.jsx?$/, loaders: ["react-hot"], - exclude: /node_modules/ - } - ] - } + exclude: /node_modules/, + }, + ], + }, }; const result = { module: { @@ -48,49 +48,49 @@ function mergeStrategySpecificTests(merge) { { test: /.jsx?$/, loaders: ["react-hot"], - exclude: /node_modules/ + exclude: /node_modules/, }, { test: /.jsx?$/, loaders: ["babel"], - exclude: /node_modules/ - } - ] - } + exclude: /node_modules/, + }, + ], + }, }; assert.deepStrictEqual( merge({ - "module.loaders": CustomizeRule.Prepend + "module.loaders": CustomizeRule.Prepend, })(a, b), result ); }); - it("should work with array wildcards", function() { + it("should work with array wildcards", function () { const a = { entry: { main: ["./src\\config\\main.ts"], polyfills: ["./src\\config\\polyfills.ts"], - styles: ["./src\\assets\\styles\\styles.sass"] - } + styles: ["./src\\assets\\styles\\styles.sass"], + }, }; const b = { entry: { - main: ["./src\\config\\main.playground.ts"] - } + main: ["./src\\config\\main.playground.ts"], + }, }; const result = { entry: { main: ["./src\\config\\main.playground.ts"], polyfills: ["./src\\config\\polyfills.ts"], - styles: ["./src\\assets\\styles\\styles.sass"] - } + styles: ["./src\\assets\\styles\\styles.sass"], + }, }; assert.deepStrictEqual( merge({ - "entry.*": CustomizeRule.Replace + "entry.*": CustomizeRule.Replace, })(a, b), result ); diff --git a/test/merge-with-customize.test.ts b/test/merge-with-customize.test.ts index 6fc88e2..fec4f2c 100644 --- a/test/merge-with-customize.test.ts +++ b/test/merge-with-customize.test.ts @@ -2,124 +2,124 @@ import assert from "assert"; import webpack from "webpack"; import { mergeWithCustomize } from "../resolve"; -describe("Merge", function() { +describe("Merge", function () { customizeMergeTests(mergeWithCustomize); }); function customizeMergeTests(merge) { - it("should allow overriding array behavior", function() { + it("should allow overriding array behavior", function () { const first = { - entry: ["a"] + entry: ["a"], }; const second = { - entry: ["b"] + entry: ["b"], }; assert.deepStrictEqual( merge({ customizeArray(a) { return a; - } + }, })(first, second), first ); }); - it("should pass key to array customizer", function() { + it("should pass key to array customizer", function () { let receivedKey; const first = { - entry: ["a"] + entry: ["a"], }; const second = { - entry: ["b"] + entry: ["b"], }; const result = merge({ customizeArray(a, _, key) { receivedKey = key; return a; - } + }, })(first, second); assert.strictEqual(receivedKey, "entry"); assert.deepStrictEqual(result, first); }); - it("should allow overriding object behavior", function() { + it("should allow overriding object behavior", function () { const first = { entry: { - a: "foo" - } + a: "foo", + }, }; const second = { entry: { - a: "bar" - } + a: "bar", + }, }; assert.deepStrictEqual( merge({ customizeObject(a) { return a; - } + }, })(first, second), first ); }); - it("should pass key to object customizer", function() { + it("should pass key to object customizer", function () { let receivedKey; const first = { entry: { - a: "foo" - } + a: "foo", + }, }; const second = { entry: { - a: "bar" - } + a: "bar", + }, }; const result = merge({ customizeObject(a, _, key) { receivedKey = key; return a; - } + }, })(first, second); assert.strictEqual(receivedKey, "entry"); assert.deepStrictEqual(result, first); }); - it("should customize plugins", function() { + it("should customize plugins", function () { let receivedKey; const config1 = { plugins: [ new webpack.DefinePlugin({ "process.env": { - NODE_ENV: JSON.stringify("development") - } + NODE_ENV: JSON.stringify("development"), + }, }), - new webpack.HotModuleReplacementPlugin() - ] + new webpack.HotModuleReplacementPlugin(), + ], }; const config2 = { plugins: [ new webpack.DefinePlugin({ - __CLIENT__: true + __CLIENT__: true, }), new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, - contextRegExp: /moment$/ + contextRegExp: /moment$/, }), - new webpack.HotModuleReplacementPlugin() - ] + new webpack.HotModuleReplacementPlugin(), + ], }; merge({ customizeArray(_, __, key) { receivedKey = key; - } + }, })(config1, config2); assert.strictEqual(receivedKey, "plugins"); diff --git a/test/merge-with-rules.test.ts b/test/merge-with-rules.test.ts index 2722edf..fc9d754 100644 --- a/test/merge-with-rules.test.ts +++ b/test/merge-with-rules.test.ts @@ -2,36 +2,36 @@ import assert from "assert"; import { mergeWithRules } from "../resolve"; import { CustomizeRule } from "../src/types"; -describe("Merge with rules", function() { - it("should replace with nested notation", function() { +describe("Merge with rules", function () { + it("should replace with nested notation", function () { const base = { entry: "demo", module: { rules: [ { test: /\.scss$/, - loaders: ["css-loader"] + loaders: ["css-loader"], }, { test: /\.css$/, - loaders: ["style-loader"] - } - ] - } + loaders: ["style-loader"], + }, + ], + }, }; const development = { module: { rules: [ { test: /\.scss$/, - loaders: ["style-loader"] + loaders: ["style-loader"], }, { test: /\.less$/, - loaders: ["css-loader"] - } - ] - } + loaders: ["css-loader"], + }, + ], + }, }; const result = { entry: "demo", @@ -39,18 +39,18 @@ describe("Merge with rules", function() { rules: [ { test: /\.scss$/, - loaders: ["style-loader"] + loaders: ["style-loader"], }, { test: /\.css$/, - loaders: ["style-loader"] + loaders: ["style-loader"], }, { test: /\.less$/, - loaders: ["css-loader"] - } - ] - } + loaders: ["css-loader"], + }, + ], + }, }; assert.deepStrictEqual( @@ -58,44 +58,44 @@ describe("Merge with rules", function() { module: { rules: { test: CustomizeRule.Match, - loaders: CustomizeRule.Replace - } - } + loaders: CustomizeRule.Replace, + }, + }, })(base, development), result ); }); - it("should append with nested notation", function() { + it("should append with nested notation", function () { const base = { module: { rules: [ { test: /\.scss$/, - loaders: ["css-loader"] - } - ] - } + loaders: ["css-loader"], + }, + ], + }, }; const development = { module: { rules: [ { test: /\.scss$/, - loaders: ["style-loader"] - } - ] - } + loaders: ["style-loader"], + }, + ], + }, }; const result = { module: { rules: [ { test: /\.scss$/, - loaders: ["css-loader", "style-loader"] - } - ] - } + loaders: ["css-loader", "style-loader"], + }, + ], + }, }; assert.deepStrictEqual( @@ -103,44 +103,44 @@ describe("Merge with rules", function() { module: { rules: { test: CustomizeRule.Match, - loaders: CustomizeRule.Append - } - } + loaders: CustomizeRule.Append, + }, + }, })(base, development), result ); }); - it("should prepend with nested notation", function() { + it("should prepend with nested notation", function () { const base = { module: { rules: [ { test: /\.scss$/, - loaders: ["css-loader"] - } - ] - } + loaders: ["css-loader"], + }, + ], + }, }; const development = { module: { rules: [ { test: /\.scss$/, - loaders: ["style-loader"] - } - ] - } + loaders: ["style-loader"], + }, + ], + }, }; const result = { module: { rules: [ { test: /\.scss$/, - loaders: ["style-loader", "css-loader"] - } - ] - } + loaders: ["style-loader", "css-loader"], + }, + ], + }, }; assert.deepStrictEqual( @@ -148,24 +148,24 @@ describe("Merge with rules", function() { module: { rules: { test: CustomizeRule.Match, - loaders: CustomizeRule.Prepend - } - } + loaders: CustomizeRule.Prepend, + }, + }, })(base, development), result ); }); - it("should merge #146", function() { + it("should merge #146", function () { const a = { module: { rules: [ { test: /\.css$/, - use: [{ loader: "style-loader" }, { loader: "sass-loader" }] - } - ] - } + use: [{ loader: "style-loader" }, { loader: "sass-loader" }], + }, + ], + }, }; const b = { module: { @@ -176,13 +176,13 @@ describe("Merge with rules", function() { { loader: "style-loader", options: { - modules: true - } - } - ] - } - ] - } + modules: true, + }, + }, + ], + }, + ], + }, }; const result = { module: { @@ -193,14 +193,14 @@ describe("Merge with rules", function() { { loader: "style-loader", options: { - modules: true - } + modules: true, + }, }, - { loader: "sass-loader" } - ] - } - ] - } + { loader: "sass-loader" }, + ], + }, + ], + }, }; assert.deepStrictEqual( @@ -210,16 +210,16 @@ describe("Merge with rules", function() { test: CustomizeRule.Match, use: { loader: CustomizeRule.Match, - options: CustomizeRule.Replace - } - } - } + options: CustomizeRule.Replace, + }, + }, + }, })(a, b), result ); }); - it("should merge #149", function() { + it("should merge #149", function () { const base = { module: { rules: [ @@ -227,15 +227,15 @@ describe("Merge with rules", function() { test: /\.scss$/, loaders: [ { - loader: "css-loader" + loader: "css-loader", }, { - loader: "resolve-url-loader" - } - ] - } - ] - } + loader: "resolve-url-loader", + }, + ], + }, + ], + }, }; const development = { module: { @@ -246,13 +246,13 @@ describe("Merge with rules", function() { { loader: "css-loader", options: { - sourceMap: true - } - } - ] - } - ] - } + sourceMap: true, + }, + }, + ], + }, + ], + }, }; const result = { module: { @@ -263,16 +263,16 @@ describe("Merge with rules", function() { { loader: "css-loader", options: { - sourceMap: true - } + sourceMap: true, + }, }, { - loader: "resolve-url-loader" - } - ] - } - ] - } + loader: "resolve-url-loader", + }, + ], + }, + ], + }, }; assert.deepStrictEqual( @@ -282,46 +282,46 @@ describe("Merge with rules", function() { test: CustomizeRule.Match, loaders: { loader: CustomizeRule.Match, - options: CustomizeRule.Replace - } - } - } + options: CustomizeRule.Replace, + }, + }, + }, })(base, development), result ); }); - it("should merge #157", function() { + it("should merge #157", function () { const base = { entry: "demo", module: { rules: [ { test: /\.scss$/, - loaders: ["css-loader"] + loaders: ["css-loader"], }, { test: /\.css$/, - loaders: ["style-loader"] - } - ] + loaders: ["style-loader"], + }, + ], }, - plugins: [{ name: "StylelintPlugin" }] + plugins: [{ name: "StylelintPlugin" }], }; const development = { module: { rules: [ { test: /\.scss$/, - loaders: ["style-loader"] + loaders: ["style-loader"], }, { test: /\.less$/, - loaders: ["css-loader"] - } - ] + loaders: ["css-loader"], + }, + ], }, - plugins: [{ name: "MiniCssExtractPlugin" }] + plugins: [{ name: "MiniCssExtractPlugin" }], }; const result = { entry: "demo", @@ -329,19 +329,19 @@ describe("Merge with rules", function() { rules: [ { test: /\.scss$/, - loaders: ["style-loader"] + loaders: ["style-loader"], }, { test: /\.css$/, - loaders: ["style-loader"] + loaders: ["style-loader"], }, { test: /\.less$/, - loaders: ["css-loader"] - } - ] + loaders: ["css-loader"], + }, + ], }, - plugins: [{ name: "StylelintPlugin" }, { name: "MiniCssExtractPlugin" }] + plugins: [{ name: "StylelintPlugin" }, { name: "MiniCssExtractPlugin" }], }; assert.deepStrictEqual( @@ -349,118 +349,118 @@ describe("Merge with rules", function() { module: { rules: { test: CustomizeRule.Match, - loaders: CustomizeRule.Replace - } - } + loaders: CustomizeRule.Replace, + }, + }, })(base, development), result ); }); - it("should merge with a parser loader", function() { + it("should merge with a parser loader", function () { const defaultConfig = { module: { rules: [ { parser: { - system: false - } + system: false, + }, }, { test: /\.(js|ts)x?$/, exclude: /node_modules/, use: [ { - loader: "babel-loader" - } - ] + loader: "babel-loader", + }, + ], }, { test: /\.css$/i, include: [/node_modules/, /src/], use: [ { - loader: "style-loader" + loader: "style-loader", }, { loader: "css-loader", options: { - modules: false - } - } - ] - } - ] - } + modules: false, + }, + }, + ], + }, + ], + }, }; const localConfig = { module: { rules: [ { test: /\.html$/i, - use: [{ loader: "html-loader" }] + use: [{ loader: "html-loader" }], }, { test: /\.css$/i, use: [ { - loader: "style-loader" + loader: "style-loader", }, { loader: "css-loader", options: { - importLoaders: 1 - } + importLoaders: 1, + }, }, { - loader: "postcss-loader" - } - ] - } - ] - } + loader: "postcss-loader", + }, + ], + }, + ], + }, }; const result = { module: { rules: [ { parser: { - system: false - } + system: false, + }, }, { test: /\.(js|ts)x?$/, exclude: /node_modules/, use: [ { - loader: "babel-loader" - } - ] + loader: "babel-loader", + }, + ], }, { test: /\.css$/i, include: [/node_modules/, /src/], use: [ { - loader: "style-loader" + loader: "style-loader", }, { loader: "css-loader", options: { - importLoaders: 1 - } + importLoaders: 1, + }, }, { - loader: "postcss-loader" - } - ] + loader: "postcss-loader", + }, + ], }, { test: /\.html$/i, - use: [{ loader: "html-loader" }] - } - ] - } + use: [{ loader: "html-loader" }], + }, + ], + }, }; assert.deepStrictEqual( @@ -470,27 +470,27 @@ describe("Merge with rules", function() { test: CustomizeRule.Match, use: { loader: CustomizeRule.Match, - options: CustomizeRule.Replace - } - } - } + options: CustomizeRule.Replace, + }, + }, + }, })(defaultConfig, localConfig), result ); }); - it("should merge without rule (#151)", function() { + it("should merge without rule (#151)", function () { const module = { rules: { test: CustomizeRule.Match, use: { loader: CustomizeRule.Match, - options: CustomizeRule.Replace - } - } + options: CustomizeRule.Replace, + }, + }, }; const _mergeWithoutRule = mergeWithRules({ - module + module, }); const config = { resolve: { extensions: [".js"] } }; diff --git a/test/merge.test.ts b/test/merge.test.ts index 5538680..8cd3c47 100644 --- a/test/merge.test.ts +++ b/test/merge.test.ts @@ -3,63 +3,63 @@ import merge, { merge as defaultMerge } from "../resolve"; import mergeTests from "../helpers/merge-tests"; import loadersKeys from "../helpers/loaders-keys"; -describe("Merge", function() { +describe("Merge", function () { normalMergeTests(merge); mergeTests(merge); - it("should export default merge", function() { + it("should export default merge", function () { assert.strictEqual(merge, defaultMerge); }); }); function normalMergeTests(merge) { - loadersKeys.forEach(function(loadersKey) { + loadersKeys.forEach(function (loadersKey) { normalMergeTest(merge, loadersKey); }); } function normalMergeTest(merge, loadersKey) { - it("should throw with an empty configuration", function() { + it("should throw with an empty configuration", function () { assert.throws(() => merge(), { name: "TypeError", - message: "Merging undefined is not supported" + message: "Merging undefined is not supported", }); }); - it("should throw with undefined 1/4", function() { + it("should throw with undefined 1/4", function () { assert.throws(() => merge(undefined), { name: "TypeError", - message: "Merging undefined is not supported" + message: "Merging undefined is not supported", }); }); - it("should throw with undefined 2/4", function() { + it("should throw with undefined 2/4", function () { assert.throws(() => merge([undefined]), { name: "TypeError", - message: "Merging undefined is not supported" + message: "Merging undefined is not supported", }); }); - it("should throw with undefined 2/4", function() { + it("should throw with undefined 2/4", function () { const result = { devServer: null }; assert.throws( () => merge( { - devServer: { base: true } + devServer: { base: true }, }, undefined, result ), { name: "TypeError", - message: "Merging undefined is not supported" + message: "Merging undefined is not supported", } ); }); - it("should throw with undefined 3/4", function() { + it("should throw with undefined 3/4", function () { const result = { devServer: null }; assert.throws( @@ -67,28 +67,28 @@ function normalMergeTest(merge, loadersKey) { merge( undefined, { - devServer: { base: true } + devServer: { base: true }, }, result ), { name: "TypeError", - message: "Merging undefined is not supported" + message: "Merging undefined is not supported", } ); }); - it("should work with an empty array", function() { + it("should work with an empty array", function () { assert.deepStrictEqual(merge([]), {}); }); - it("should override with null (#144)", function() { + it("should override with null (#144)", function () { const result = { devServer: null }; assert.deepStrictEqual( merge( { - devServer: { base: true } + devServer: { base: true }, }, result ), @@ -96,11 +96,11 @@ function normalMergeTest(merge, loadersKey) { ); }); - it("should allow merging optimization config to itself (#145)", function() { + it("should allow merging optimization config to itself (#145)", function () { const config = { optimization: { runtimeChunk: { - name: "runtime" + name: "runtime", }, splitChunks: { @@ -112,191 +112,194 @@ function normalMergeTest(merge, loadersKey) { name: "clientApplication", test: /applications\/client/, chunks: "all", - enforce: true - } - } - } - } + enforce: true, + }, + }, + }, + }, }; assert.deepStrictEqual(merge(config, config), config); }); - it("should error on promise", function() { + it("should error on promise", function () { const a = { - module: {} + module: {}, }; assert.throws(() => merge(Promise.resolve(a), Promise.resolve(a)), { name: "TypeError", - message: "Promises are not supported" + message: "Promises are not supported", }); }); - it("should error on promises inside an array", function() { + it("should error on promises inside an array", function () { const a = { - module: {} + module: {}, }; assert.throws(() => merge([Promise.resolve(a), Promise.resolve(a)]), { name: "TypeError", - message: "Promises are not supported" + message: "Promises are not supported", }); }); - it("should append recursive structures with " + loadersKey, function() { + it("should append recursive structures with " + loadersKey, function () { const a = { - module: {} + module: {}, }; a.module[loadersKey] = [ { test: /\.js$/, - loader: "a" + loader: "a", }, { test: /\.jade$/, - loader: "a" - } + loader: "a", + }, ]; const b = { - module: {} + module: {}, }; b.module[loadersKey] = [ { test: /\.css$/, - loader: "b" + loader: "b", }, { test: /\.sass$/, - loader: "b" - } + loader: "b", + }, ]; const result = { - module: {} + module: {}, }; result.module[loadersKey] = [ { test: /\.js$/, - loader: "a" + loader: "a", }, { test: /\.jade$/, - loader: "a" + loader: "a", }, { test: /\.css$/, - loader: "b" + loader: "b", }, { test: /\.sass$/, - loader: "b" - } + loader: "b", + }, ]; assert.deepStrictEqual(merge(a, b), result); }); - it("should not override loader string values with " + loadersKey, function() { - const a = {}; - a[loadersKey] = [ - { - test: /\.js$/, - loader: "a" - } - ]; - const b = {}; - b[loadersKey] = [ - { - test: /\.js$/, - loader: "b" - }, - { - test: /\.css$/, - loader: "b" - } - ]; - const result = {}; - result[loadersKey] = [ - { - test: /\.js$/, - loader: "a" - }, - { - test: /\.js$/, - loader: "b" - }, - { - test: /\.css$/, - loader: "b" - } - ]; + it( + "should not override loader string values with " + loadersKey, + function () { + const a = {}; + a[loadersKey] = [ + { + test: /\.js$/, + loader: "a", + }, + ]; + const b = {}; + b[loadersKey] = [ + { + test: /\.js$/, + loader: "b", + }, + { + test: /\.css$/, + loader: "b", + }, + ]; + const result = {}; + result[loadersKey] = [ + { + test: /\.js$/, + loader: "a", + }, + { + test: /\.js$/, + loader: "b", + }, + { + test: /\.css$/, + loader: "b", + }, + ]; - assert.deepStrictEqual(merge(a, b), result); - }); + assert.deepStrictEqual(merge(a, b), result); + } + ); - it("should not append loaders with " + loadersKey, function() { + it("should not append loaders with " + loadersKey, function () { const a = {}; a[loadersKey] = [ { test: /\.js$/, - loaders: ["a"] - } + loaders: ["a"], + }, ]; const b = {}; b[loadersKey] = [ { test: /\.js$/, - loaders: ["b"] + loaders: ["b"], }, { test: /\.css$/, - loader: "b" - } + loader: "b", + }, ]; const result = {}; result[loadersKey] = [ { test: /\.js$/, - loaders: ["a"] + loaders: ["a"], }, { test: /\.js$/, - loaders: ["b"] + loaders: ["b"], }, { test: /\.css$/, - loader: "b" - } + loader: "b", + }, ]; assert.deepStrictEqual(merge(a, b), result); }); - it("should duplicate loaders with " + loadersKey, function() { + it("should duplicate loaders with " + loadersKey, function () { const a = {}; a[loadersKey] = [ { test: /\.js$/, - loaders: ["a"] - } + loaders: ["a"], + }, ]; const b = {}; b[loadersKey] = [ { test: /\.js$/, - loaders: ["a", "b"] - } + loaders: ["a", "b"], + }, ]; const result = {}; result[loadersKey] = [ { test: /\.js$/, - loaders: ["a"] + loaders: ["a"], }, { test: /\.js$/, - loaders: ["a", "b"] - } + loaders: ["a", "b"], + }, ]; assert.deepStrictEqual(merge(a, b), result); @@ -304,42 +307,42 @@ function normalMergeTest(merge, loadersKey) { it( "should not override query options for the same loader with " + loadersKey, - function() { + function () { const a = {}; a[loadersKey] = [ { test: /\.js$/, - loaders: ["a?1"] - } + loaders: ["a?1"], + }, ]; const b = {}; b[loadersKey] = [ { test: /\.js$/, - loaders: ["a?2", "b"] - } + loaders: ["a?2", "b"], + }, ]; const c = {}; c[loadersKey] = [ { test: /\.js$/, - loaders: ["a", "b?3"] - } + loaders: ["a", "b?3"], + }, ]; const result = {}; result[loadersKey] = [ { test: /\.js$/, - loaders: ["a?1"] + loaders: ["a?1"], }, { test: /\.js$/, - loaders: ["a?2", "b"] + loaders: ["a?2", "b"], }, { test: /\.js$/, - loaders: ["a", "b?3"] - } + loaders: ["a", "b?3"], + }, ]; assert.deepStrictEqual(merge(a, b, c), result); @@ -348,13 +351,13 @@ function normalMergeTest(merge, loadersKey) { it( "should not allow overriding with an empty array in " + loadersKey, - function() { + function () { const a = {}; a[loadersKey] = [ { test: /\.js$/, - loaders: ["a?1"] - } + loaders: ["a?1"], + }, ]; const b = {}; b[loadersKey] = []; diff --git a/test/unique.test.ts b/test/unique.test.ts index b152512..80c0284 100644 --- a/test/unique.test.ts +++ b/test/unique.test.ts @@ -2,79 +2,79 @@ import assert from "assert"; import webpack from "webpack"; import { mergeWithCustomize, unique } from "../resolve"; -describe("Unique", function() { - it("should allow unique definitions", function() { +describe("Unique", function () { + it("should allow unique definitions", function () { const output = mergeWithCustomize({ customizeArray: unique( "plugins", ["HotModuleReplacementPlugin"], - plugin => plugin.constructor && plugin.constructor.name - ) + (plugin) => plugin.constructor && plugin.constructor.name + ), })( { - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [new webpack.HotModuleReplacementPlugin()], }, { - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [new webpack.HotModuleReplacementPlugin()], } ); const expected = { - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [new webpack.HotModuleReplacementPlugin()], }; assert.deepStrictEqual(output, expected); }); - it("should pick the last plugin (#119)", function() { + it("should pick the last plugin (#119)", function () { const output = mergeWithCustomize({ customizeArray: unique( "plugins", ["DefinePlugin"], - plugin => plugin.constructor && plugin.constructor.name - ) + (plugin) => plugin.constructor && plugin.constructor.name + ), })( { plugins: [ new webpack.DefinePlugin({ - a: "a" - }) - ] + a: "a", + }), + ], }, { plugins: [ new webpack.DefinePlugin({ - b: "b" - }) - ] + b: "b", + }), + ], } ); const expected = { plugins: [ new webpack.DefinePlugin({ - b: "b" - }) - ] + b: "b", + }), + ], }; assert.deepStrictEqual(output, expected); }); - it("should not lose any plugins", function() { + it("should not lose any plugins", function () { const output = mergeWithCustomize({ customizeArray: unique( "plugins", ["HotModuleReplacementPlugin"], - plugin => plugin.constructor && plugin.constructor.name - ) + (plugin) => plugin.constructor && plugin.constructor.name + ), })( { plugins: [ new webpack.HotModuleReplacementPlugin(), - new webpack.DefinePlugin({}) - ] + new webpack.DefinePlugin({}), + ], }, { - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [new webpack.HotModuleReplacementPlugin()], } ); // The HMR plugin is picked from the last one due to @@ -82,37 +82,37 @@ describe("Unique", function() { const expected = { plugins: [ new webpack.DefinePlugin({}), - new webpack.HotModuleReplacementPlugin() - ] + new webpack.HotModuleReplacementPlugin(), + ], }; assert.deepStrictEqual(output, expected); }); - it("should check only against named plugins (#125)", function() { + it("should check only against named plugins (#125)", function () { const output = mergeWithCustomize({ customizeArray: unique( "plugins", ["DefinePlugin"], - plugin => plugin.constructor && plugin.constructor.name - ) + (plugin) => plugin.constructor && plugin.constructor.name + ), })( { plugins: [ new webpack.HotModuleReplacementPlugin(), - new webpack.DefinePlugin({}) - ] + new webpack.DefinePlugin({}), + ], }, { - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [new webpack.HotModuleReplacementPlugin()], } ); const expected = { plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.DefinePlugin({}), - new webpack.HotModuleReplacementPlugin() - ] + new webpack.HotModuleReplacementPlugin(), + ], }; assert.deepStrictEqual(output, expected); From 927e049a54cb9cc537cf8ed4de9893825e8122f8 Mon Sep 17 00:00:00 2001 From: Tomasz Wielga Date: Tue, 8 Dec 2020 15:39:06 +0100 Subject: [PATCH 02/12] unique merge array customisation fix (#162) Closes #161. --- README.md | 2 ++ src/unique.ts | 31 ++++++++++++------------------- test/unique.test.ts | 32 +++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 71b7f5f..5f5df52 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,8 @@ The first `` is the config property to look through for duplicates. `` represents the values that should be unique when you run the field => field function on each duplicate. +When the order of elements of the `` in the first configuration differs from the order in the second configuration, the latter is preserved. + ```javascript const { mergeWithCustomize, unique } = require("webpack-merge"); diff --git a/src/unique.ts b/src/unique.ts index c7d29fa..e4c5542 100644 --- a/src/unique.ts +++ b/src/unique.ts @@ -3,26 +3,19 @@ function mergeUnique( uniques: string[], getter: (a: object) => string ) { + let uniquesSet = new Set(uniques) return (a: [], b: [], k: string) => - k === key && [ - ...difference(a, b, (item) => uniques.indexOf(getter(item))), - ...b, - ]; -} - -function difference(a: object[], b: object[], cb: (v: object) => number) { - const ret = a.filter((v, i) => { - const foundA = cb(v); - const foundB = cb(b[i] || {}); - - if (foundA >= 0 && foundB >= 0) { - return foundA !== foundB; - } - - return true; - }); - - return ret; + (k === key) && Array.from( + [...a, ...b] + .map((it: object) => ({ key: getter(it), value: it })) + .map(({ key, value }) => ({ key: (uniquesSet.has(key) ? key : value), value: value})) + .reduce( + (m, { key, value}) => { + m.delete(key); // This is required to preserve backward compatible order of elements after a merge. + return m.set(key, value) + }, + new Map()) + .values()) } export default mergeUnique; diff --git a/test/unique.test.ts b/test/unique.test.ts index 80c0284..e03ed27 100644 --- a/test/unique.test.ts +++ b/test/unique.test.ts @@ -59,7 +59,7 @@ describe("Unique", function () { assert.deepStrictEqual(output, expected); }); - it("should not lose any plugins", function () { + it("should not lose any trailing plugins", function () { const output = mergeWithCustomize({ customizeArray: unique( "plugins", @@ -89,6 +89,36 @@ describe("Unique", function () { assert.deepStrictEqual(output, expected); }); + it("should not lose any leading plugins", function () { + const output = mergeWithCustomize({ + customizeArray: unique( + "plugins", + ["HotModuleReplacementPlugin"], + (plugin) => plugin.constructor && plugin.constructor.name + ), + })( + { + plugins: [ + new webpack.DefinePlugin({}), + new webpack.HotModuleReplacementPlugin(), + ], + }, + { + plugins: [new webpack.HotModuleReplacementPlugin()], + } + ); + // The HMR plugin is picked from the last one due to + // default ordering! + const expected = { + plugins: [ + new webpack.DefinePlugin({}), + new webpack.HotModuleReplacementPlugin(), + ], + }; + + assert.deepStrictEqual(output, expected); + }); + it("should check only against named plugins (#125)", function () { const output = mergeWithCustomize({ customizeArray: unique( From 28d6b98c85ff7132a0e49ad4e7b20534d9804905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Tue, 8 Dec 2020 15:41:12 +0100 Subject: [PATCH 03/12] chore: Add @trombka to contributors --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 222e726..cfe1350 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -20,3 +20,4 @@ - [Daniel Ruf](https://github.com/DanielRuf) - Remove bitHound from the README as it closed down. #102 - [Adrien Harnay](https://github.com/adrienharnay) - Update README to comply with webpack API. #108 - [Paweł Lula](https://github.com/desfero) - Support `oneOf` at `merge.smart`. #111 +- [Tomasz Wielga](https://github.com/trombka) - Allow `mergeUnique` to work with arbitrary order. #161 From f311804334c84899033de6d73ac9a942ad647149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Tue, 8 Dec 2020 15:41:58 +0100 Subject: [PATCH 04/12] chore: Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 150ba16..13a028e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.4.1 / 2020-12-08 + +- Fix - Allow `mergeUnique` to work with arbitrary order. #161 + ## 5.4.0 / 2020-10-30 - Fix - Fall back correctly in `mergeWithRules` for cases that aren't matched. #157 #158 From 105007e7731626c23867efd3b7363fe77ecff0a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Tue, 8 Dec 2020 15:42:06 +0100 Subject: [PATCH 05/12] 5.4.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ba60027..d3da93f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "webpack-merge", - "version": "5.4.0", + "version": "5.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fe2107f..43db0b2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "webpack-merge", "description": "Variant of merge that's useful for webpack configuration", "author": "Juho Vepsalainen ", - "version": "5.4.0", + "version": "5.4.1", "scripts": { "build": "tsc", "format": "prettier . --write --ignore-path .gitignore", From c2e79a08833276bc29ef1b7f8a100a0ede12d8c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Thu, 10 Dec 2020 09:42:46 +0100 Subject: [PATCH 06/12] feat - Add a syntax for adjusting merge behavior without matching (#152) Closes #151. Closes #159. --- README.md | 6 +- src/index.ts | 26 ++++++++ test/merge-with-rules.test.ts | 108 ++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5f5df52..e9641d0 100644 --- a/README.md +++ b/README.md @@ -150,8 +150,8 @@ The first `` is the config property to look through for duplicates. `` represents the values that should be unique when you run the field => field function on each duplicate. -When the order of elements of the `` in the first configuration differs from the order in the second configuration, the latter is preserved. - +When the order of elements of the `` in the first configuration differs from the order in the second configuration, the latter is preserved. + ```javascript const { mergeWithCustomize, unique } = require("webpack-merge"); @@ -241,7 +241,7 @@ assert.deepStrictEqual( ); ``` -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. +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. ## Using with TypeScript diff --git a/src/index.ts b/src/index.ts index 424e93d..ecc30dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -106,6 +106,10 @@ function mergeWithRules(rules: Rules) { return mergeWithRule({ currentRule, a, b }); } + if (typeof currentRule === "string") { + return mergeIndividualRule({ currentRule, a, b }); + } + return undefined; }, }); @@ -207,6 +211,28 @@ function mergeWithRule({ return ret.concat(b.filter((o) => !bAllMatches.includes(o))); } +function mergeIndividualRule({ + currentRule, + a, + b, +}: { + currentRule: CustomizeRule; + a: Array; + b: Array; +}) { + // What if there's no match? + switch (currentRule) { + case CustomizeRule.Append: + return a.concat(b); + case CustomizeRule.Prepend: + return b.concat(a); + case CustomizeRule.Replace: + return b; + } + + return a; +} + function last(arr) { return arr[arr.length - 1]; } diff --git a/test/merge-with-rules.test.ts b/test/merge-with-rules.test.ts index fc9d754..bb540ab 100644 --- a/test/merge-with-rules.test.ts +++ b/test/merge-with-rules.test.ts @@ -496,4 +496,112 @@ describe("Merge with rules", function () { expect(() => _mergeWithoutRule(config, config)).not.toThrow(); }); + + it("should merge with append without match (#151)", function () { + const _mergeWithExplicitRule = mergeWithRules({ + resolve: { + extensions: CustomizeRule.Append, + }, + }); + const a = { resolve: { extensions: [".js"] } }; + const b = { resolve: { extensions: [".css"] } }; + const result = { resolve: { extensions: [".js", ".css"] } }; + + expect(_mergeWithExplicitRule(a, b)).toEqual(result); + }); + + it("should merge with prepend without match (#151)", function () { + const _mergeWithExplicitRule = mergeWithRules({ + resolve: { + extensions: CustomizeRule.Prepend, + }, + }); + const a = { resolve: { extensions: [".js"] } }; + const b = { resolve: { extensions: [".css"] } }; + const result = { resolve: { extensions: [".css", ".js"] } }; + + expect(_mergeWithExplicitRule(a, b)).toEqual(result); + }); + + it("should merge with replace without match (#151)", function () { + const _mergeWithExplicitRule = mergeWithRules({ + resolve: { + extensions: CustomizeRule.Replace, + }, + }); + const a = { resolve: { extensions: [".js"] } }; + const b = { resolve: { extensions: [".css"] } }; + const result = { resolve: { extensions: [".css"] } }; + + expect(_mergeWithExplicitRule(a, b)).toEqual(result); + }); + + it("should merge mixed rules", function () { + const a = { + resolve: { extensions: [".js"] }, + module: { + rules: [ + { + test: /\.css$/, + use: [{ loader: "style-loader" }, { loader: "sass-loader" }], + }, + ], + }, + }; + const b = { + resolve: { extensions: [".css"] }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: "style-loader", + options: { + modules: true, + }, + }, + ], + }, + ], + }, + }; + const result = { + resolve: { extensions: [".js", ".css"] }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: "style-loader", + options: { + modules: true, + }, + }, + { loader: "sass-loader" }, + ], + }, + ], + }, + }; + + assert.deepStrictEqual( + mergeWithRules({ + resolve: { + extensions: CustomizeRule.Append, + }, + module: { + rules: { + test: CustomizeRule.Match, + use: { + loader: CustomizeRule.Match, + options: CustomizeRule.Replace, + }, + }, + }, + })(a, b), + result + ); + }); }); From b89bc278ca3fe75aa40b22d201abab3465a3d133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Thu, 10 Dec 2020 09:44:22 +0100 Subject: [PATCH 07/12] chore: Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13a028e..dbfa87f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.5.0 / 2020-12-10 + +- Feat - Allow `mergeWithRules` to merge based on rules without a match. #151 #159 + ## 5.4.1 / 2020-12-08 - Fix - Allow `mergeUnique` to work with arbitrary order. #161 From f3f8fe720df698e5b1f00f437be19b04c9d700c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Thu, 10 Dec 2020 09:44:30 +0100 Subject: [PATCH 08/12] 5.5.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3da93f..9b0ea49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "webpack-merge", - "version": "5.4.1", + "version": "5.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 43db0b2..4316bb8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "webpack-merge", "description": "Variant of merge that's useful for webpack configuration", "author": "Juho Vepsalainen ", - "version": "5.4.1", + "version": "5.5.0", "scripts": { "build": "tsc", "format": "prettier . --write --ignore-path .gitignore", From 76ecea77050e61b6e4c0ab56f79849e640edabd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Fri, 11 Dec 2020 15:09:44 +0100 Subject: [PATCH 09/12] feat: Support merge variant for mergeWithRules Closes #163. --- CHANGELOG.md | 4 ++ README.md | 8 ++++ src/index.ts | 6 +++ src/types.ts | 1 + test/merge-with-rules.test.ts | 69 +++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbfa87f..85774c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.6.0 / 2020-12-11 + +- Feat - Support `merge` (`CustomizeRule.Merge`) for objects at `mergeWithRules`. This is useful for merging loader options for example. #163 + ## 5.5.0 / 2020-12-10 - Feat - Allow `mergeWithRules` to merge based on rules without a match. #151 #159 diff --git a/README.md b/README.md index e9641d0..8538a0f 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,14 @@ assert.deepStrictEqual( 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 items +- `prepend` (`CustomizeRule.Prepend`) - Prepends items +- `replace` (`CustomizeRule.Replace`) - Replaces items +- `merge` (`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: diff --git a/src/index.ts b/src/index.ts index ecc30dd..53b891b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -182,6 +182,10 @@ function mergeWithRule({ ? (v as Array).concat(last(bMatches)[k]) : v; break; + case CustomizeRule.Merge: + // @ts-ignore: The assumption here is that both are objects + ret[k] = { ...v, ...last(bMatches)[k] }; + break; case CustomizeRule.Prepend: ret[k] = bMatches.length > 0 ? last(bMatches)[k].concat(v) : v; break; @@ -220,6 +224,8 @@ function mergeIndividualRule({ a: Array; b: Array; }) { + console.log("checking rule", currentRule); + // What if there's no match? switch (currentRule) { case CustomizeRule.Append: diff --git a/src/types.ts b/src/types.ts index f42b47b..166ee67 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,6 +9,7 @@ export interface ICustomizeOptions { export enum CustomizeRule { Match = "match", + Merge = "merge", Append = "append", Prepend = "prepend", Replace = "replace", diff --git a/test/merge-with-rules.test.ts b/test/merge-with-rules.test.ts index bb540ab..2b4ce08 100644 --- a/test/merge-with-rules.test.ts +++ b/test/merge-with-rules.test.ts @@ -604,4 +604,73 @@ describe("Merge with rules", function () { result ); }); + + it.only("should merge objects (#163)", function () { + const _mergeWithExplicitRule = mergeWithRules({ + module: { + rules: { + test: CustomizeRule.Match, + use: { + loader: CustomizeRule.Match, + options: CustomizeRule.Merge, + }, + }, + }, + }); + const a = { + resolve: { extensions: [".js"] }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + { loader: "style-loader", options: { modules: true } }, + { loader: "sass-loader" }, + ], + }, + ], + }, + }; + const b = { + resolve: { extensions: [".css"] }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: "style-loader", + options: { + modules: true, + another: true, + }, + }, + ], + }, + ], + }, + }; + const result = { + resolve: { extensions: [".js", ".css"] }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: "style-loader", + options: { + modules: true, + another: true, + }, + }, + { loader: "sass-loader" }, + ], + }, + ], + }, + }; + + expect(_mergeWithExplicitRule(a, b)).toEqual(result); + }); }); From 3749d2015852060e8456db3dbc0e1424cb142b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Fri, 11 Dec 2020 15:10:16 +0100 Subject: [PATCH 10/12] 5.6.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b0ea49..998ffae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "webpack-merge", - "version": "5.5.0", + "version": "5.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4316bb8..bdde765 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "webpack-merge", "description": "Variant of merge that's useful for webpack configuration", "author": "Juho Vepsalainen ", - "version": "5.5.0", + "version": "5.6.0", "scripts": { "build": "tsc", "format": "prettier . --write --ignore-path .gitignore", From 6e842825e97e38906b3de8d9f9bd5b80ef687b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Fri, 11 Dec 2020 15:12:49 +0100 Subject: [PATCH 11/12] fix: Drop extraneous logging --- CHANGELOG.md | 4 ++++ src/index.ts | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85774c4..0a00e5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.6.1 / 2020-12-11 + +- Fix - Drop extraneous logging. + ## 5.6.0 / 2020-12-11 - Feat - Support `merge` (`CustomizeRule.Merge`) for objects at `mergeWithRules`. This is useful for merging loader options for example. #163 diff --git a/src/index.ts b/src/index.ts index 53b891b..17db3e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -224,8 +224,6 @@ function mergeIndividualRule({ a: Array; b: Array; }) { - console.log("checking rule", currentRule); - // What if there's no match? switch (currentRule) { case CustomizeRule.Append: From 3649212bcf03e3e015e0fdc2e1ec431afeb7242f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juho=20Veps=C3=A4l=C3=A4inen?= Date: Fri, 11 Dec 2020 15:12:53 +0100 Subject: [PATCH 12/12] 5.6.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 998ffae..34d8bdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "webpack-merge", - "version": "5.6.0", + "version": "5.6.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index bdde765..62bb4da 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "webpack-merge", "description": "Variant of merge that's useful for webpack configuration", "author": "Juho Vepsalainen ", - "version": "5.6.0", + "version": "5.6.1", "scripts": { "build": "tsc", "format": "prettier . --write --ignore-path .gitignore",