webpack提升打包速度

305 阅读1分钟

1 OneOf

webpack在处理文件时,根据module.rules中的规则一条一条进行匹配,但即时文件匹配上了,也不会停止,还会继续往后匹配。想要改变这种情况,可以使用OneOf。

module: {
    rules: [
        {
            oneOf: [
                {
    test: /.ts$/,
    use: ['ts-loader']
},
                ...
            ]
        }
    ]
}

2 Include/Exclude

在开发项目过程中,我们可能会下载第三方库或插件到node_modules里,下载下来的文件已经编译过了,可以直接使用。为了不再次编译它,提升打包速度,我们在打包时要排除它们。

注意 exclude和include只可以同时使用1个

// 以js文件为例
rules: [
    test: /.js$/,
    exclude: /node_modules/,    // 排除node_modules下的文件,其它文件都处理
    // include: path.resolve(__dirname, "../src"),  // 只处理src下的文件,其它文件不处理
    loader: "babel-loader"
]

3 eslint和babel缓存

每次打包,js文件都要经过eslint检查和babel编译,速度比较慢。开启缓存可以保存上次eslint检查和babel编译的结果,加快第2次的打包速度。

babel:

rules: [
    test: /.js$/,
    loader: "babel-loader",
    options: {
        cacheDirectory: true,   // 开启babel缓存
        cacheCompression: false,    // 关闭缓存文件压缩,(我们追求的是速度,但压缩也需要时间)
    }
]

eslint:

plugins: [
    new EslintPlugin({
        context: path.resolve(__dirname, "src"),
        exclude: "node_modules",
        cache: true,    // 开启缓存
        cacheLocation: path.resolve(    // 指定缓存路径
            __dirname,
            "../node_modules/.cache/eslintcache"
        )
    })
]

4 Thread

多线程打包,因为项目中js文件占绝大多数,所以基本上就是多进程处理js文件。

下载相应包:npm i thread-loader -d

// 获取cpu核数
const os = require("os")
const thread = os.cpus().length
// 压缩js插件,webpack内置
const TerserWebpackPlugin = require("terser-webpack-plugin")
​
// babel
rules: [
    ...,
    {
        test: /.js$/,
        use: [
            {   // thread-loader放在所有loader前面
                loader: "thread-loader",
                options: {
                    works: threads, // 线程数量
                }
            },
            {
                loader: "babel-loader",
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                }
            },
        ]
    }
]
​
// eslint
plugins: [
    new EslintPlugin({
        context: path.resolve(__dirname, "src"),
        exclude: "node_modules",
        cache: true,
        cacheLocation: path.resolve(
            __dirname,  "../node_modules/.cache/eslintcache"
        ),
        threads,    // 开启多线程和线程数量
    })
]
​
// js压缩,其实应该和eslint写一起,但为了分辨分开写
modules: {
    optimization: {
        minimizer: [
            new TerserWebpackPlugin({
                parallel: threads
            })
        ]
    }
}
​