Closed
Description
I had a quick chat with Tobias about this. As it happens, it would be valuable to be able to define strategies inline so you could achieve something like this:
merge(
require("webpack-preset-development"),
require("webpack-preset-css-modules"),
require("webpack-preset-separate-css")
)
Inline definitions would encode the information per preset since it's information we don't care about if we are merging presets.
Possible APIs:
const webpackPresetCSSModules = {
module: {
rules: {
__append: [ ... ]
}
}
};
const webpackPresetSeparateCSS = {
module: {
rules: {
__update: function(rules) {...}
}
}
};
I guess finding the right API is the hardest problem. Minimum implementation would convert the definition to the current API (adapter).
Feedback welcome!
Activity
andywer commentedon Dec 6, 2016
Hi @bebraw. I would suggest using the immutability helper unless there is some strong reason not to.
I think it does everything that needs to be supported, there will be no fighting over the API details, a bunch of people will already be familiar with it and you don't even need to write much documentation. Just link to the immutability helper's docs :)
bebraw commentedon Dec 11, 2016
I think I found something that would work well with the existing system without causing a lot of work:
_strategies
would contain the hintsmerge
would pick up. It would also delete the field in the process since it's just a hint (no value in the result).Even though React's immutability helpers are powerful, this feels like a simpler API since it's just key-value pairs.
bebraw commentedon Jan 5, 2017
@rockmacaca Any thoughts on this? This needs some direction.
I have been thinking about a different solution entirely. Maybe configuration parts need to own some dependency information. Then you could push them through a dependency resolver and figure out the correct order that way. It's a lower level solution, but it could work.
kherock commentedon Jan 6, 2017
You'll need to detail that last thought a bit more clearly for me, not sure what you mean.
I do kind of like the hints. My first immediate thought toward a solution for plugin merging is something like the following:
Not too pretty, but I'd be ok with using it. It probably needs tweaking to support plugins that take multiple arguments. Something similar could probably be used for merging functions as well.
I do think the immutability helpers are great in that they accomplish most of what the existing "strategy" implementation does. There would still need to be additional work on top of the result to support merging plugin configs and function arguments.
bebraw commentedon Jan 6, 2017
Consider something like CSS extraction and purifying. I have modeled these as
extractCSS
andpurifyCSS
functions myself. Latter depends on the former and they have to be defined in this specific order to work.If
purifyCSS
could state this dependency, then the problem of ordering could be pushed tomerge
and you wouldn't have to care about the exact order as the user.It can still be brittle, though, as the pipeline might be more complex than that.
I guess we might need more configurations to figure out a good way to handle this. The current solution (just vanilla
merge
) is totally enough for me.I wonder if the smart variant even gives that great an advantage. You get something more compact out of it, but you could argue webpack itself should do that style of work to speed up execution. If there's no performance difference, providing smart merging isn't needed at all.
magbicaleman commentedon Mar 29, 2017
I'm merging a base config, into dev config following this tutorial.
I've seperated my entry points;
dev.js
base.js
When they get merged, it seems that the entry info from
dev.js
gets appended tobase.js
, which is understandable. The issue becomes thatreact-hot-loader/patch
needs to be first.I looked into strategy and this get's the desired result;
If I wanted to accomplish this with merge(base.js, dev.js), I'm expecting the following to work, but perhaps I'm way off here
dev.js
base.js
So, I'm wondering if the proposition above would solve this. Alternatively, I could leave the
base.js
entry property blank, and add it to bothdev.js
andprod.js
.bebraw commentedon Mar 29, 2017
@magbicaleman Yeah, this particular case is a little tricky. I've found it's easier not to inherit entries for this reason. Instead I manage them per target even if that might lead to some duplication. At least you can use a vanilla
merge
then and it's easy to see what's going on.Note that
'react-hot-loader/patch'
will inject an empty module during production once they get a new beta version out. That means you can likely have it in the entry configuration always and it will do the right thing.magbicaleman commentedon Mar 29, 2017
@bebraw
This is my current entry for
dev.js
now, might as well duplicate.base.js
prod.js
My question is, do the following also need to be in
prod.js
;bebraw commentedon Mar 30, 2017
@magbicaleman You can skip
for production. Those last two entries could be skipped if you ran webpack-dev-server in inline mode but there's probably a reason why you are not.
I would write config like this:
dev.js
prod.js
If/when you have more app entries, you could push those somewhere and perhaps
.concat
them for development and consume directly for production. That would giveentry: appEntries
andentry: [... dev entries ...].concat(appEntries)
which isn't too bad.magbicaleman commentedon Mar 30, 2017
@bebraw thank you very much for all of your feedback, I pretty much did end up with your recommendation above.
andreyvolokitin commentedon Oct 24, 2019
I currently have 2 mutually exclusive loaders (for the same test group) which should replace each other during merging. The only way to get this done is to set global merge strategy for
module.rules
toreplace
? Then all my loaders will be replaced instead of merging, but it would be nice to apply this strategy inline...bebraw commentedon Jul 3, 2020
I am adding support for wildcard matching in #135 and I believe that solves the problem discussed here in a nice way.