HappyPack 并行编译提高 Webpack 构建速度
HappyPack 通过并行转换文件使初始 webpack 构建更快。
维护模式通知
我对这个项目的兴趣正在消退,主要是因为我没有像过去那样使用 JavaScript。此外,Webpack 的本机性能正在提高,(我希望)它很快就会使这个插件变得不必要。
请参阅有关 Webpack 4 和thread-loader的 FAQ 条目。
用法
npm install --save-dev happypack
HappyPack 提供了一个插件和一个加载器来完成它的工作,所以你必须同时使用它们来启用它。
通常,您定义加载器规则来告诉 webpack 如何处理某些文件。使用 HappyPack,您可以进行切换,以便将加载器传递给 HappyPack 的插件,而不是告诉 webpack 使用happypack/loader.
以下是显示这些步骤的示例配置。
// @file: webpack.config.js
const HappyPack = require('happypack');
exports.module = {
rules: [
{
test: /.js$/,
// 1) replace your original list of loaders with "happypack/loader":
// loaders: [ 'babel-loader?presets[]=es2015' ],
use: 'happypack/loader',
include: [ /* ... */ ],
exclude: [ /* ... */ ]
}
]
};
exports.plugins = [
// 2) create the plugin:
new HappyPack({
// 3) re-add the loaders you replaced above in #1:
loaders: [ 'babel-loader?presets[]=es2015' ]
})
];就是这样。现在匹配的源.js$将被移交给 HappyPack,HappyPack 将使用您指定的加载器并行转换它们(babel-loader 在本例中。)
配置
这些是您在实例化插件时可以传递给插件的参数。 loaders是唯一必需的参数。
loaders: Array
每个条目都包含将转换文件的加载程序的名称(或绝对路径)和传递给它的可选查询字符串。这看起来类似于您传递给 webpackloader配置的内容。
小心!HappyPack 不适用于所有webpack 加载器,因为某些加载器 API 不受支持,有关当前 Loader API 支持的更多详细信息,请参阅此 wiki 页面。
以下符号是官方支持的,并且都是等效的:
{
loaders: [
// a string with embedded query for options
'babel-loader?presets[]=es2015',
{
loader: 'babel-loader'
},
// "query" string
{
loader: 'babel-loader',
query: '?presets[]=es2015'
},
// "query" object
{
loader: 'babel-loader',
query: {
presets: [ 'es2015' ]
}
},
// Webpack 2+ "options" object instead of "query"
{
loader: 'babel-loader',
options: {
presets: [ 'es2015' ]
}
}
]
}id: String
这个快乐插件的唯一 ID。加载器使用它来知道它应该与哪个插件通信。
通常,除非您定义了多个 HappyPack 插件,否则您不需要指定这一点,在这种情况下,您需要不同的 ID 来区分它们。有关详细信息,请参阅本节。
默认为:"1"
threads: Number
此数字表示将生成多少个 Node VM HappyPack 用于编译源文件。经过大量的修补,我发现 4 可以产生最好的结果。这个值的回报肯定会递减,而超过 8 的值实际上会减慢我的速度。
请记住,这仅在执行初始构建时才相关, 因为 HappyPack 将在之后切换到同步模式(即在watch 模式中。)
默认为:3
threadPool: HappyThreadPool
用于检索工作线程的预定义线程池。通常,这是由每个HappyPlugin实例在内部管理的,但您可以覆盖此行为以获得更好的结果。
线程池部分解释了如何以及何时使用它。
默认为:null
verbose: Boolean
启用它以将状态消息从 HappyPack 记录到 STDOUT,如启动横幅等。
默认为:true
verboseWhenProfiling: Boolean
如果您希望 HappyPack 即使在webpack --profile运行时仍能产生其输出,请启用此选项。由于引入了这个变量,HappyPack 在构建配置文件时将保持沉默,以免破坏 webpack 的任何 JSON 输出(即在使用时--json也是如此。)
默认为:false
debug: Boolean
启用此选项可将 HappyPack 的诊断消息记录到 STDOUT。对故障排除很有用。
默认为:false
这个怎么运作
HappyPack 位于 webpack 和您的主要源文件(如 JS 源文件)之间,其中大部分加载器转换发生。每次 webpack 解析一个模块时,HappyPack 都会获取它及其所有依赖项并将这些文件分发到多个工作“线程”。
这些线程实际上是调用转换器的简单节点进程。当检索到编译后的版本时,HappyPack 将其提供给它的加载器并最终提供给您的块。
使用多个实例
可以为不同类型的源/转换定义多个 HappyPack 插件。只需为每个插件传递一个唯一的 id 并确保将其传递给它们的加载器:
// @file webpack.config.js
exports.plugins = [
new HappyPack({
id: 'jsx',
threads: 4,
loaders: [ 'babel-loader' ]
}),
new HappyPack({
id: 'styles',
threads: 2,
loaders: [ 'style-loader', 'css-loader', 'less-loader' ]
})
];
exports.module.rules = [
{
test: /\.js$/,
use: 'happypack/loader?id=jsx'
},
{
test: /\.less$/,
use: 'happypack/loader?id=styles'
},
]现在.js文件将由第一个 babel-loader用于转换它们的 Happy 插件处理,而.less文件将由第二个使用样式加载器的插件处理。
共享线程池
通常,您在内部创建的每个 HappyPack 插件都会创建自己的线程,用于运行加载程序。但是,如果您使用多个 HappyPack 插件,最好自己创建一个线程池,然后将插件配置为共享该池,从而最大限度地减少其中线程的空闲时间。
这是一个使用 5 个线程的自定义池的示例,它将在 JS 和 SCSS/LESS/任何来源的加载器之间共享:
// @file: webpack.config.js
var HappyPack = require('happypack');
var happyThreadPool = HappyPack.ThreadPool({ size: 5 });
module.exports = {
// ...
plugins: [
new HappyPack({
id: 'js',
threadPool: happyThreadPool,
loaders: [ 'babel-loader' ]
}),
new HappyPack({
id: 'styles',
threadPool: happyThreadPool,
loaders: [ 'style-loader', 'css-loader', 'less-loader' ]
})
]
};基准
对于我测试过的主存储库,它有大约 3067 个模块,构建时间从 39 秒下降到了大约 10 秒。
以下是执行构建的各种状态的概要:
| Elapsed (ms) | Happy? | Using DLLs? |
|---|---|---|
| 39851 | NO | NO |
| 37393 | NO | YES |
| 14605 | YES | NO |
| 13925 | YES | NO |
| 11877 | YES | NO |
| 9228 | YES | YES |
上面的构建是在一台 12 核机器上的 Linux 下运行的。
常问问题
它适用于 Webpack 2 和 3 吗?
是的。您应该使用版本 >= 4.0.1(HappyPack)。
Webpack 4 有必要吗?
简短的回答:也许不是。
长答案:现在有一个加载器形式的竞争插件,用于在多个线程中处理文件,这正是 HappyPack 所做的。它是一个加载器而不是一个插件(或两者,如果是 HP),这一事实使得配置变得更加简单。看看线程加载器,如果它对你有用——那很好,否则你可以试试 HappyPack 看看哪个更适合你。
YMMV。
它适用于 TypeScript 吗?
简短的回答是:是的,它终于做到了!更长的答案是您需要在“仅转译”模式下使用 ts-loader ,然后使用特殊插件 fork-ts-checker-notifier-webpack-plugin执行静态类型检查。
更多信息可以在 ts-loader “happypack mode” 部分中找到,您可以参考显示此操作的 示例。
非常感谢 @johnnyreilly、@aindlq、@piotr-oles、@abergs 和许多其他人完成这项工作。
它适用于装载机 XYZ 吗?
我们在这个 wiki 页面中跟踪加载器支持。一些加载器可能需要额外的配置才能使其工作。
如果您尝试使用的加载器未在此处列出,您可以参考此wiki 页面以查看支持哪些加载器 API。如果您的 loader 使用任何不受支持的 API,它很可能无法与 HappyPack 一起使用。
作为一般规则,任何在选项中接受“函数”的加载器都不会工作,除非它也接受从文件中读取这些选项,就像 babel-loader.babelrc和 postcss-loader 一样。
它在 Windows 下工作吗?
是的,从 4.0.0 版开始应该。如果您在 Windows 上使用该插件时遇到问题,请随时提问。
上一篇: webpack-build 构建器
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!


发布评论