[meta:edit-log]: # "2019/08/14,2019/08/27"
[meta:title]: # "Unpacking Webpack"
[meta:keywords]: # "webpack, profiling, plugin, optimization"
[meta:description]: # "Some tip for hacking Webpack."
Here's some tip for hacking Webpack
> this is for `webpack@4`, and works better for big webpack project (compile time above 1.5 min)
> also, though it's not well organized, do read **ALL** of the webpack doc.
## better understand what happened
with `ProgressPlugin` and some code, you can get a rough idea of that is being processed:
```js
const createProgressPlugin = () => {
const timeStart = Date.now()
let timePrev = timeStart
return new webpack.ProgressPlugin((percentage, message, ...args) => {
const timeNow = Date.now()
if (timeNow - timePrev <= 200) return
console.log(`[${Math.round(percentage * 100)}%|${timeNow - timeStart}ms|+${timeNow - timePrev}ms] ${message} - ${args.join(' ')}`)
timePrev = timeNow
})
}
```
for not-that-big project, with `debug.ProfilingPlugin`,
a detailed timeline can be generated:
(but if the output json exceeds 300MiB, Chrome Devtool may just crash loading)
```js
new webpack.debug.ProfilingPlugin({
outputPath: '__PROFILING_EVENTS__.json'
})
```
with process monitor like `htop`, check the process CPU usage,
better make sure the CPU is fully utilized, especially when multi-thread is enabled.
## multi-thread loader magic
use `cache-loader` before `thread-loader`,
load the cache (fs+gunzip) is not that costly,
reversing the order is slower
when using `thread-loader`, consider passing most file through it,
including normally excluded `node_modules` js files,
and consider set [`parallelism: 512`](https://webpack.js.org/configuration/other-options/#parallelism),
so enough pending module can be found, and keep all thread busy
> some loader/plugin do not work well with `thread-loader`,
> make sure exclude loader/plugin with function in config from `thread-loader`
## minimal plugin
if plugin is not needed in current build,
do not pass it in the plugin array and disable it,
instead consider remove it, and skip `require` it is much better