code splitting doesn't work in child compilations
See original GitHub issueFeature request
What is the expected behavior?
Code splitting should work in child compilations without the need for additional configuration.
What is motivation or use case for adding/changing the behavior?
Without an intimate understanding of all of webpack’s internal plugins and the hooks they use, it’s unclear what functionality you get and don’t get when when creating a child compiler. I found it surprising that a child compiler cannot, at minimum, build an app that uses code splitting given that code splitting is not a feature that you usually have to enable otherwise.
In my use case, I’d like to have a 2nd compilation that’s almost identical to the parent compilation with the exception that a different optimization
option is set. Since the input to both compilations are identical I’d like to reuse as much work as possible across compilations so that webpack doesn’t perform 2x the work.
This appears to be the minimal amount of code required to create a compilation similar to the parent:
module.exports = class CopyCatCompilerPlugin {
apply(mainCompiler) {
mainCompiler.hooks.make.tapAsync(
'ChildCompilerPlugin',
(compilation, callback) => {
const childCompiler = compilation.createChildCompiler(
'child',
mainCompiler.options.output,
[
new JsonpTemplatePlugin(), // required since `thisCompilation` taps are not copied
]
);
// required since `compile` taps are not copied by default
childCompiler.hooks.compile.taps = mainCompiler.hooks.compile.taps.slice();
// prevent errors like "Conflict: Multiple assets emit to the same filename 0.js"
// since the child compilation will result is identically named split chunks
childCompiler.options.output.chunkFilename = `child-${mainCompiler.options.output.chunkFilename}`;
// filter out unwanted optimization plugins here
// add identical entry with a different bundle name
new SingleEntryPlugin(
mainCompiler.context,
'./src/index.js',
'main-2'
).apply(childCompiler);
childCompiler.runAsChild(callback);
}
);
}
};
In general, it seems like the pattern of running multiple almost-identical compilations is useful in cases where you want to compile to different targets while not duplicating work across compilation. Or when you want webpack to bundle a test runner bundle but not have the test bundle entry affect your code splits.
Is there a better approach to this problem so that it’s easy to replicate the parent compilation with slightly different options while maintaining performance?
For context, I’m on webpack 4.27.1 but cannot migrate to webpack 5 since I have many custom plugins and loaders that will require work to make compatible with webpack 5.
How should this be implemented in your opinion?
Have Compiler.createChildCompiler
ensure that the JsonpTempaltePlugin
is applied.
Are you willing to work on this yourself?
yes
Issue Analytics
- State:
- Created 3 years ago
- Comments:11 (6 by maintainers)
That’s something that we would love to do soon but I was curious what the best solution today would look like.
It sounds like our best bet might just be to run these builds in parallel so that build times don’t suffer too much. I’ll close this issue but I’m happy to hear any other thoughts if you have them.
I’ll open a documentation PR soon to add more details about the
createChildCompiler
API.Thanks, @alexander-akait .