Webpack的多进程打包是通过利用多个子进程同时处理不同的模块来加速打包过程的技术。这种技术可以提高打包效率,减少等待时间,使得项目构建更快。
使用多进程打包的好处在于,它可以将一些比较耗时的操作分配到不同的进程中进行并行处理,从而提高打包效率。这使得打包过程更加高效,节省了时间和资源。另外,和单进程打包相比,多进程打包也有助于避免进程卡死或异常终止的问题。
对于大型项目或需要进行复杂操作的项目,采用多进程打包可以更快地完成项目构建,提高效率,减少等待时间,使开发人员可以更快地检验代码。
但是对于小型项目,比如我这个学习的demo其实使用多进程打包反而会比单进程慢,应为没多开启一个进程都要耗费一定时间和性能
我们启动进程的数量就是我们 CPU 的核数。
1. 获取 CPU 的核数,因为每个电脑都不一样。
// nodejs核心模块,直接使用
const os = require("os");
// cpu核数
const threads = os.cpus().length;
2. 下载包
npm i thread-loader -D
3. 核心配置
const os = require('os')
const threads = os.cpus().length
const path = require('path')
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, '../dist'),
filename: 'static/js/main.js'
},
module: {
rules: [
{
test: /\.m?js$/, // 转译哪些文件
exclude: /(node_modules|bower_components)/, // 排除哪些文件夹中的js文件不用转译
use: [
{
loader: "thread-loader", // 开启多进程
options: {
workers: threads, // 数量
},
},
{
loader: "babel-loader",
options: {
// presets: ['@babel/preset-env'] // 添加预设,转译js文件
cacheDirectory: true, // 开启babel编译缓存
cacheCompression: false, // 缓存文件不要压缩
},
},
],
},
]
},
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src"),
exclude: "node_modules", // 默认值
cache: true, // 开启缓存
// 缓存目录
cacheLocation: path.resolve(
__dirname,
"../node_modules/.cache/.eslintcache"
),
threads, // 开启多进程
}),
],
optimization: {
minimize: true,
minimizer: [
// css压缩也可以写到optimization.minimizer里面,效果一样的
new CssMinimizerPlugin(),
// 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
new TerserPlugin({
parallel: threads // 开启多进程
})
],
},
}
4. 完整代码
// Node.js的核心模块,专门用来处理文件路径
const path = require("path");
// nodejs核心模块,直接使用
const os = require("os");
const threads = os.cpus().length;
const ESLintWebpackPlugin = require("eslint-webpack-plugin"); // 引入 ESLint 插件
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 引入 html-webpack-plugin 插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 引入 mini-css-extract-plugin 插件
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // 压缩css
const TerserPlugin = require("terser-webpack-plugin");
// 获取处理样式的Loaders
const getStyleLoaders = (preProcessor) => {
return [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
preProcessor,
].filter(Boolean);
};
module.exports = {
// 入口
// 相对路径和绝对路径都行
entry: "./src/main.js",
// 输出
output: {
// path: 文件输出目录,必须是绝对路径
// path.resolve()方法返回一个绝对路径
// __dirname 当前文件的文件夹绝对路径
path: path.resolve(__dirname, "../dist"),
// filename: js文件输出文件名
filename: "js/main.js",
clean: true, // 自动将上次打包目录资源清空
},
// 加载器
module: {
rules: [
{
oneOf: [
{
// 用来匹配 .css 结尾的文件
test: /\.css$/,
// use 数组里面 Loader 执行顺序是从右到左
use: getStyleLoaders(),
},
{
// 用来匹配.less结尾的文件
test: /\.less$/,
use: getStyleLoaders("less-loader"),
},
{
test: /\.s[ac]ss$/,
use: getStyleLoaders("sass-loader"),
},
{
// 用来匹配图片文件
test: /\.(png|jpe?g|gif|webp)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024, // 小于10kb的图片会被base64处理
},
},
generator: {
// 将图片文件输出到 images 目录中
// 将图片文件命名 [hash:8][ext][query]
// [hash:8]: hash值取8位
// [ext]: 使用之前的文件扩展名
// [query]: 添加之前的query参数
filename: "images/[hash:8][ext][query]",
},
},
{
test: /\.(ttf|woff2?|map4|map3|avi)$/,
type: "asset/resource", // 以文件资源的形式输出
generator: {
filename: "media/[hash:8][ext][query]", // 输出到media目录中
},
},
{
test: /\.m?js$/, // 转译哪些文件
exclude: /(node_modules|bower_components)/, // 排除哪些文件夹中的js文件不用转译
use: [
{
loader: "thread-loader", // 开启多进程
options: {
workers: threads, // 数量
},
},
{
loader: "babel-loader",
options: {
// presets: ['@babel/preset-env'] // 添加预设,转译js文件
cacheDirectory: true, // 开启babel编译缓存
cacheCompression: false, // 缓存文件不要压缩
},
},
],
},
],
},
],
},
// 插件
plugins: [
new ESLintWebpackPlugin({
// 指定检查文件的根目录
context: path.resolve(__dirname, "../src"),
cache: true, // 开启缓存
// 缓存目录
cacheLocation: path.resolve(
__dirname,
"../node_modules/.cache/.eslintcache"
),
threads, // 开启多进程
}),
new HtmlWebpackPlugin({
// 以 public/index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../public/index.html"),
}),
// 提取css成单独文件
new MiniCssExtractPlugin({
// 定义输出文件名和目录
filename: "css/main.css",
}),
// css压缩
// new CssMinimizerPlugin(),
],
optimization: {
minimize: true,
minimizer: [
// css压缩也可以写到optimization.minimizer里面,效果一样的
new CssMinimizerPlugin(),
// 当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
new TerserPlugin({
parallel: threads // 开启多进程
})
],
},
// 模式
mode: "production", // 生产模式
devtool: "source-map", // 生产环境下使用
};