-
-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merging two module.rules just appends #146
Comments
Were you using smart merging before? If so, I added features for customizing the merge to cover the cases it tried to handle before. Do you have the whole configuration somewhere? I could try to propose a clean alternative for the use case. |
Yep we have used smart merging before: https://github.com/just-jeb/angular-builders/blob/master/packages/custom-webpack/src/webpack-config-merger.ts#L12 Currently this is the update: import { mergeWithCustomize, customizeObject, customizeArray } from 'webpack-merge';
import { Configuration } from 'webpack';
import { merge, remove } from 'lodash';
import { MergeStrategyRules } from './custom-webpack-builder-config';
export function mergeConfigs(
webpackConfig1: Configuration,
webpackConfig2: Configuration,
mergeStrategies: MergeStrategyRules = {},
replacePlugins = false
): Configuration {
// always remove duplicates from config 1 and replace with plugin from config 2
// if wanted merge config 1 plugin into 2
if (webpackConfig1.plugins && webpackConfig2.plugins) {
webpackConfig2.plugins = webpackConfig2.plugins.map(plugin => {
const foundDuplicate = webpackConfig1.plugins.findIndex(
p => p.constructor.name === plugin.constructor.name
);
if (foundDuplicate !== -1) {
if (!replacePlugins) {
plugin = merge(webpackConfig1.plugins[foundDuplicate], plugin);
}
remove(webpackConfig1.plugins, (_, i) => i === foundDuplicate);
}
return plugin;
});
}
const mergedConfig = mergeWithCustomize({
customizeArray: customizeArray(mergeStrategies),
customizeObject: customizeObject(mergeStrategies),
})(webpackConfig1, webpackConfig2);
return mergedConfig;
} |
I would propose a new merge strategy "merge" which would look like this in that specific case:
|
@muuvmuuv Yeah, using a strategy would fit well. I'll go that way (might need a day or two due to other work). |
I gave this one initial go. It looks like adding a strategy won't work for this case as it's too complex. It contains a combination of uniqueness and merging which makes it tricky to map to the current semantics. To work, it would have to perform a merge over Something like this: const output = mergeWithCustomize({
customizeArray: unique(
"module.rules",
// These are individual rules
(a, b) => mergeWithCustomize({
customizeArray: customizeArray({
// Replace since we want the latter only for use that matches
use: "replace"
}),
}),
// Extract tests from rules so they can be merged
rule => rule.test
),
})(configs); I would have to add support for nested keys and extend the second parameter to @muuvmuuv What do you think of the above? |
Hey @bebraw, sorry for the late response. Since this is for a commercial project I haven't looked into it through the weekend. I will test this today but does this include a fallback for anything else than "module.rules"? |
@muuvmuuv Hi, the code above doesn't work yet. It's something I could develop on top of the current API without breaking the current design. |
I am getting typing errors. Maybe it would be good to add webpack typings to the "unique" function, since
I also had to do this: (rule: RuleSetRule) => rule.test |
Oh, sorry then I misunderstood that! So just take the above as hints ^^. |
Yeah, that's what I meant. I'll have to extend the signature and implementation. 👍 |
What do you think about an array or single input for const output = mergeWithCustomize({
customizeArray: [
customizeArray(mergeStrategies), // merge by default rules
unique( // add specific use case
'module.rules',
() =>
mergeWithCustomize({
customizeArray: customizeArray({
// replace since we want the latter only for use that matches
use: 'replace',
}),
}),
(rule: RuleSetRule) => rule.test
)
// another custom rule
// now merge with a third config e.g.
// etc. etc.
],
})(webpackConfig1, webpackConfig2); |
@muuvmuuv Yeah, that's a good idea since then you could build more matchers. I have to check the code to understand the implications but I see the use case. |
I tried out the API proposal but it's not that simple as we have to check against I found that you can do this with the current API: merge({
customizeArray(a, b, key) {
if (key === "module.rules") {
return a.map((v) => {
let bv = b.find(
({ test }) => test.toString() === v.test.toString()
);
if (!bv) {
return v;
}
return {
...v,
use: v.use.map((uv) => {
let bvv = bv.use.find(({ loader }) => loader === uv.loader);
if (!bvv) {
return uv;
}
return {
...uv,
options: {
...(uv.options || {}),
...bvv.options,
},
};
}),
};
});
}
return b;
},
})(configs) I think the next step is to write a helper to simplify the code above. It feels like there's something like The problem is a bit tricky as it doesn't fall into regular object merge and it has checks in it against specific fields. |
I think the best I can do will look something like this: mergeArrays(
'test',
(a, b) => ({
...merge(a, b),
use: mergeArrays('use', merge)
})
)(a, b) Since |
I think this is the best I can do: mergeWithCustomize({
customizeArray: customizeArray({
"module.rules[test].use[loader]": CustomizeRule.Replace
})
}) I'll need to write some kind of parser to deal with the syntax and then map from that to the code but it's the perhaps the cleanest approach and it allows us to use strategies against specific arrays like in the current design. |
I have a solution at #150. Can you check and comment? Thanks! |
You should be able to do this type of merge in |
Great, Thank you! Sorry for not responding but somehow my browser just crashed every time I have loaded this issue. All others work fine just on this one it just freazes. Pretty strange but seemed to be fixed from GH or Chromium. |
@muuvmuuv No probs. Let me know if you have any further issues. I think the current API is fairly powerful and it should allow most of what smart merging did but in an explicit manner (less magic). |
This is the test I want to run but it seems that the latest version does not longer merge rules.
Output is:
The text was updated successfully, but these errors were encountered: