I'm working on an old project with a lot of code. This project uses Webpack 3.8.1 and I'm trying to update to 4.4.1, and it's a real obstacle course!
The main pain is that the projects uses the CommonsChunkPlugin:
new CommonsChunkPlugin({
name: 'common',
minChunks: 3,
chunks: _.without(_.keys(entry), 'ace-iframe', 'custom-theme-ace'),
}),
new CommonsChunkPlugin({
name: 'vendors',
minChunks(module, count) {
return isVendorModule(module) && count >= 2;
},
chunks: _.without(_.keys(entry), 'ace-iframe', 'custom-theme-ace'),
})
I know that Webpack 4 does not provide CommonsChunkPlugin anymore. A big thanks a lot to the below articles, they've saved hours of researches:
- https://gist.github.com/sokra/1522d586b8e5c0f5072d7565c2bee693
- https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
Thanks to these amazing links, I've replaced CommonsChunkPlugin with these lines:
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
priority: 50,
name: 'vendors',
chunks: 'async',
reuseExistingChunk: true,
minChunks: 2,
enforce: true,
test: /node_modules/,
},
common: {
name: 'common',
priority: 10,
chunks: 'async',
reuseExistingChunk: true,
minChunks: 2,
enforce: true,
},
},
},
},
},
Thanks to this config, the application is correctly building, chunks are created and the app is running as expected. But the building time is really slow: more than 7 minutes!
Funny thing, if I totally remove the whole optimization.splitChunks
configuration, the applications still works perfectly, and the building time is still around 7 minutes: it's totally like what I've done in optimization.splitChunks
is useless.
I've tried to change the chunks
properties: to be honest I don't really understand its role...
If I set them to all
, the build is way quicker: around 1 minute.
But unfortunately, the generated files from my entries points are not running well: Webpack seems to wait that the chunks are loaded before executing my own code:
// Code from webpack
function checkDeferredModules() {
var result;
for(var i = 0; i < deferredModules.length; i++) {
var deferredModule = deferredModules[i];
var fulfilled = true;
for(var j = 1; j < deferredModule.length; j++) {
var depId = deferredModule[j];
if(installedChunks[depId] !== 0) fulfilled = false;
}
// If I understand well, Webpack checked that deferred modules are loaded
if(fulfilled) {
// If so, it runs the code of my entry point
deferredModules.splice(i--, 1);
result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
}
}
return result;
}
Please tell me I am not wrong here: Webpack seems to wait deferred modules to be loaded, but it does not run the code which is actually loading them... How am I suppose to make this work?
In brief:
- with
chunks
set toasync
: all is working well, but building time is not viable (more than 7 minutes) - with
chunks
set toall
: building time is correct (around 1 minute), but my code is not running ¯\_(ツ)_/¯
Sorry for this long post, but if someone can help me to make all of this working with correct building time, it would be perfect.
Or at least helping me to understand how all of this is supposed to work, official documentation is not very helpful :(
Thanks in advance!
EDIT: I've tried to continue with chunks
set to async
, despite the 7mn building time.
I have 20 entries points, and if I add an import
instruction importing jQuery and jQuery-UI in one of them, building time is doubling.
If I add it into 5 files, the build crashes:
<--- Last few GCs --->
[15623:0x103000000] 222145 ms: Mark-sweep 1405.0 (1717.4) -> 1405.2 (1717.4) MB, 671.3 / 0.0 ms allocation failure GC in old space requested [15623:0x103000000] 222807 ms: Mark-sweep 1405.2 (1717.4) -> 1405.0 (1667.9) MB, 662.4 / 0.0 ms last resort GC in old space requested [15623:0x103000000] 223475 ms: Mark-sweep 1405.0 (1667.9) -> 1405.1 (1645.4) MB, 667.1 / 0.0 ms last resort GC in old space requested
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x1b6415c25ee1 1: fromString(aka fromString) [buffer.js:~298] [pc=0x1973a88756aa](this=0x1b6462b82311 ,string=0x1b642d3fe779 ,encoding=0x1b6462b82311 ) 3: from [buffer.js:177] [bytecode=0x1b6488c3b7c1 offset=11](this=0x1b644b936599 ,value=0x1b642d3fe779 ,encodingOrOffset=0x1b6462b82311
>> FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Out of memory... I think setting chunks
to async
is not the correct way to solve this issue :/