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 上使用该插件时遇到问题,请随时提问。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: webpack-build 构建器
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论