[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 // debounce, 200ms, drop for every progress update
    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({
  // view in Chrome DevTools, should start with: `Chromium --args --js-flags="--max_old_space_size=6144"`
  // check: https://github.com/webpack/webpack/issues/7689#issuecomment-459117090
  outputPath: '__PROFILING_EVENTS__.json' // very big 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