Skip to content

Commit

Permalink
feat - Add a syntax for adjusting merge behavior without matching (#152)
Browse files Browse the repository at this point in the history
Closes #151.
Closes #159.
  • Loading branch information
bebraw authored Dec 10, 2020
1 parent 105007e commit c2e79a0
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 3 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ 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.
When the order of elements of the `<field>` in the first configuration differs from the order in the second configuration, the latter is preserved.

```javascript
const { mergeWithCustomize, unique } = require("webpack-merge");

Expand Down Expand Up @@ -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

Expand Down
26 changes: 26 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ function mergeWithRules(rules: Rules) {
return mergeWithRule({ currentRule, a, b });
}

if (typeof currentRule === "string") {
return mergeIndividualRule({ currentRule, a, b });
}

return undefined;
},
});
Expand Down Expand Up @@ -207,6 +211,28 @@ function mergeWithRule({
return ret.concat(b.filter((o) => !bAllMatches.includes(o)));
}

function mergeIndividualRule({
currentRule,
a,
b,
}: {
currentRule: CustomizeRule;
a: Array<any>;
b: Array<any>;
}) {
// 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];
}
Expand Down
108 changes: 108 additions & 0 deletions test/merge-with-rules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
});
});

0 comments on commit c2e79a0

Please sign in to comment.