本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-02-26
随着项目越来越大,文件数量越来越多的时候,webpack
的构建就会越来越慢。
因为运行在node
上的webpack
依然是单线程模式,需要一个一个的处理任务。
HappyPack
就是用来解决这个问题的一个插件,将任务分解成多个子进程,子进程处理完后再将结果交给主线程(与web worker
模式一样)。
将所有需要通过Loader
处理的文件先交给happypack/loader
去处理,然后有HappyPack
统一分配,每通过 new HappyPack()
实例化一个HappyPack
,其实就是告诉HappyPack
核心调度器如何通过一系列的Loader
去转换一类文件,并且可以指定如何为这类转换操作分配子进程。
核心调度器运行在主进程中,也就是运行webpack
的进程中,核心调度器将一个个任务分配给当前空闲的子进程,子进程处理完毕后将结果发送给核心调度器,数据交换是通过进程间的通信API
来实现的,核心调度器收到子进程处理完毕的结果后,会通知webpack
该文件已处理完毕。
// webpack.config.js
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HappyPack = require('happypack');
module.exports = {
// JS 执行入口文件
entry: {
main: './main.js',
},
output: {
// 把所有依赖的模块合并输出到一个 bundle.js 文件
filename: '[name].js',
// 输出文件都放到 dist 目录下
path: path.resolve(__dirname, './dist'),
},
module: {
rules: [
{
test: /\.js$/,
// 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
use: ['happypack/loader?id=babel'],
// 排除 node_modules 目录下的文件
// node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
exclude: path.resolve(__dirname, 'node_modules'),
},
{
// 把对 .css 文件的处理转交给 id 为 css 的 HappyPack 实例
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: ['happypack/loader?id=css'],
}),
},
]
},
plugins: [
new HappyPack({
// 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
id: 'babel',
// 如何处理 .js 文件,用法和 Loader 配置中一样
loaders: ['babel-loader?cacheDirectory'],
// loaders: [
// {
// loader: 'babel-loader',
// options: {
// presets: [ 'es2015' ]
// }
// }
// ]
}),
new HappyPack({
id: 'css',
// 如何处理 .css 文件,用法和 Loader 配置中一样
loaders: ['css-loader'],
}),
new ExtractTextPlugin({
filename: `[name].css`,
}),
],
devtool: 'source-map' // 输出 source-map 方便直接调试 ES6 源码
};
实例化HappyPack
插件时,除了传入id
和loaders
两个参数,还支持如下参数:
threads
:代表开启几个子进程去处理这一类型的文件,默认是3
个,必须是整数。
verbose
:是否允许HappyPack
输出日志,默认是true 。
threadPool
:代表共享进程池,即多个HappyPack
实例都使用同一个共享进程池中的子进程去处理任务,以防止资源占用过多
const HappyPack = require('happypack');
// 构建出共享进程池,在进程池中包含5个子进程
const happyThreadPool = HappyPack.ThreadPool({ size : 5 }) ;
new HappyPack({
id: 'css' ,
//如何处理.css 文件,用法和Loader 配置中的一样
loaders: ['css-loader'],
//使用共享进程池中的子进程去处理任务
threadPool : happyThreadPool,
}),
用来压缩js
文件的ParallelUglifyPlugin
插件 也是使用多进程的方式去压缩文件