《Webpack5 核心原理与应用实践》学习笔记-> webpack并行构建

简介: 《Webpack5 核心原理与应用实践》学习笔记-> webpack并行构建


js是一门单线程编程语言,无法完全发挥多核cpu的所有性能,那么如何在webpack中并行构建资源,完整的利用cpu的性能呢?

这里带来了4个技术方案,就是下面这些,接下来就看他们有什么特性,和如何使用的吧。


  • HappyPack:多进程方式运行资源加载(Loader)逻辑;
  • Thread-loader:Webpack 官方出品,同样以多进程方式运行资源加载逻辑;
  • Parallel-Webpack:多进程方式运行多个 Webpack 构建实例;
  • TerserWebpackPlugin:支持多进程方式执行代码压缩、uglify 功能。


HappyPack


HappyPack是将文件加载(loader)进行拆分,让每一种类型的文件单独新建一个子进程中解析,让多种类型的文件并行执行,执行完成之后再将结果返回给webpack,使用方法如下:


  1. 安装依赖:npm i -D happypack
  2. 使用happypack


使用happypack需要将原有的配置进行改造,happypack本身是插件使用方式,需要将loader配置传入到happypack的插件实例化作为初始参数,原本的loader需要替换成happypack提供的loader,如下:


// 原本的使用方式
const path = require("path");
module.exports = {
    entry: './main.js',
    output: {
        path: path.resolve(__dirname, './dist')
    },
    module: {
        rules: [
            {
                test: /\.(png|jpg|bmp|svg)$/,
                type: "asset"
            },
            {
                test: /\.js/,
                use: ['babel-loader']
            },
            {
                test: /\.css/,
                use: ['css-loader']
            }
        ]
    }
}


// 使用 happypack 的方式
const path = require("path");
const HappyPack = require('happypack');
module.exports = {
    entry: './main.js',
    output: {
        path: path.resolve(__dirname, './dist')
    },
    module: {
        rules: [
            {
                test: /\.(png|jpg|bmp|svg)$/,
                type: "asset"
            },
            {
                test: /\.js$/,
                use: 'happypack/loader?id=js'
            },
            {
                test: /\.css/,
                use:  'happypack/loader?id=css'
            }
        ]
    },
    plugins: [
        new HappyPack({
            id: 'js',
            use: ['babel-loader']
        }),
        new HappyPack({
            id: 'css',
            use: ['style-loader']
        })
    ]
}

猛一看,配置变多了,看看就好了,我自己测试发现构建失败,然后上了github看了一下,4年没更新了,作者也表示不再维护了,这里就权当了解一下历史。


他配置的plugins就是相当于new一个就创建一个新的子线程,然后里面的参数,就是处理对应文件的loader就在这个线程中处理,多个文件就可以并发构建,增加构建效率。


Thread-loader


Thread-loaderwebpack官方提供的多线程并行构建的工具,对比happypack那肯定是更稳定,更便捷了,但是他们的功能都类似,直接来看如何使用:


  1. 安装npm i -D thread-loader
  2. 配置


const path = require("path");
module.exports = {
    mode: "production",
    entry: './main.js',
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: "[name].js"
    },
    module: {
        rules: [
            {
                test: /.(png|jpg|bmp|svg)$/,
                type: "asset"
            },
            {
                test: /.js/,
                use: ['thread-loader', 'babel-loader'], // 直接将 thread-loader 加到最前面就可以了,在它后面的 loader 就会在一个单独的线程池中运行
            },
            {
                test: /.css/,
                use: ['style-loader', 'css-loader'], // 这个没加因为加上去就报错
            }
        ]
    }
}

需要注意的是使用thread-loader也有限制,下面来自官方文档


在 worker 池(worker pool)中运行的 loader 是受到限制的。例如:

  • 这些 loader 不能产生新的文件。
  • 这些 loader 不能使用定制的 loader API(也就是说,通过插件)。
  • 这些 loader 无法获取 webpack 的选项设置。
    每个 worker 都是一个单独的有 600ms 限制的 node.js 进程。同时跨进程的数据交换也会被限制。
    请仅在耗时的 loader 上使用


文档中还有很多配置项可以使用,这里就不一一介绍了,介绍完了感觉有点像文档搬运工。


Parallel-Webpack


上面的两个loader的作用域是在文件解析这一块,之前介绍流程中有讲过,文件解析后面还有文件生成,所以咧就有了一个这个玩意,不过这个玩意并不是把文件解析、文件生成啥的都搞一个线程去处理,而是对webpack的配置对象,每一个配置对象开辟独立的线程处理,是可以和上面两个工具并存处理构建。


  1. 安装:npm i -D parallel-webpack
  2. 不需要配置,直接使用,命令行:npx parallel-webpack


当然上面这样直接使用肯定是看不到效果的,只是配置同普通的weppack相同:


const path = require("path");
module.exports = [
    {
        mode: "production",
        entry: './main.js',
        output: {
            path: path.resolve(__dirname, './dist'),
            filename: "[name]-amd.js",
            library: {
                type: "amd"
            }
        },
        module: {
            rules: [
                {
                    test: /.(png|jpg|bmp|svg)$/,
                    type: "asset"
                },
                {
                    test: /.js/,
                    use: ['thread-loader', 'babel-loader']
                },
                {
                    test: /.css/,
                    use: ['style-loader', 'css-loader']
                }
            ]
        }
    },
    {
        mode: "production",
        entry: './main.js',
        output: {
            path: path.resolve(__dirname, './dist'),
            filename: "[name]-cmd.js",
            library: {
                type: 'commonjs'
            }
        },
        module: {
            rules: [
                {
                    test: /.(png|jpg|bmp|svg)$/,
                    type: "asset"
                },
                {
                    test: /.js/,
                    use: ['thread-loader', 'babel-loader']
                },
                {
                    test: /.css/,
                    use: ['style-loader', 'css-loader']
                }
            ]
        }
    }
]

上面是导出两个配置(就是把刚刚写的案例复制了一下),使用的libaray属性输出不同的包,之前讲过如果直接使用webpack进行构建,会因为js语言的特性,构建时间会加倍,使用这种方式就可以并行构建,减少构建时间。


并行压缩


Webpack4 默认使用 Uglify-js 实现代码压缩,Webpack5 之后则升级为 Terser —— 一种性能与兼容性更好的 JavaScript 代码压缩混淆工具,两种组件都原生实现了多进程并行压缩能力。


  1. 安装: npm i -D terser-webpack-plugin
  2. 配置


const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
    // 省略其他配置
    optimization: {
        minimize: true,
        minimizer: [new TerserPlugin({
            parallel: 2, // 这里的默认值为 true,数据类型: Boolean|Number
        })]
    }
}

这个插件就是对文件进行压缩混淆的,当然这一块如果项目庞大,也是很耗时的,所以就有了一个并行压缩工具,加快构建速度。


总结


javascript的特性注定无法完全发挥cpu多核计算的能力,但是也不是完全限制死了,javascript是单线程,那只是代表一个js进程是单线程,开辟多个进程进行处理是否就是多线程呢?这是不是可以说明js不是单线程呢?


上面是玩笑话,多线程数据可以互相访问,这种多进程数据是无法直接互通的,但是处理多个不相关的业务还是OK的,于是就有了这次的webpack并行构建。


目录
相关文章
|
2月前
|
缓存 前端开发 算法
Webpack 进阶:深入理解其工作原理与优化策略
Webpack 进阶:深入理解其工作原理与优化策略
46 2
|
2月前
|
缓存 前端开发 JavaScript
|
3月前
|
前端开发 JavaScript 开发者
webpack打包机制,构建过程和配置
webpack打包机制,构建过程和配置
19 0
|
4月前
|
自然语言处理 JavaScript 前端开发
webpack 的热更新是如何做到的?原理是什么?
webpack 的热更新是如何做到的?原理是什么?
38 0
|
4月前
|
JSON 监控 测试技术
《Webpack5 核心原理与应用实践》学习笔记-> 提升插件健壮性
《Webpack5 核心原理与应用实践》学习笔记-> 提升插件健壮性
53 0
|
4月前
|
缓存 前端开发 API
《Webpack5 核心原理与应用实践》学习笔记-> webpack插件开发基础
《Webpack5 核心原理与应用实践》学习笔记-> webpack插件开发基础
63 0
|
4月前
|
前端开发 JavaScript 测试技术
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader运行与调试
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader运行与调试
36 0
|
4月前
|
存储 缓存 JavaScript
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader开发技巧
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader开发技巧
43 1
|
4月前
|
缓存 监控 JavaScript
《Webpack5 核心原理与应用实践》学习笔记-> webpack极致性能优化
《Webpack5 核心原理与应用实践》学习笔记-> webpack极致性能优化
32 1
|
1月前
|
JavaScript 前端开发
webpack成长指北第9章---webpack如何对icon字体进行打包
webpack成长指北第9章---webpack如何对icon字体进行打包
33 1