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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 《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并行构建。


目录
相关文章
|
1月前
|
监控 前端开发 JavaScript
Webpack 中 HMR 插件的工作原理
【10月更文挑战第23天】可以进一步深入探讨 HMR 工作原理的具体细节、不同场景下的应用案例,以及与其他相关技术的结合应用等方面的内容。通过全面、系统地了解 HMR 插件的工作原理,能够更好地利用这一功能,为项目的成功开发提供有力保障。同时,要不断关注技术的发展动态,以便及时掌握最新的 HMR 技术和最佳实践。
|
1月前
|
缓存 前端开发 JavaScript
Webpack 动态加载的原理
【10月更文挑战第23天】Webpack 动态加载通过巧妙的机制和策略,实现了模块的按需加载和高效运行,提升了应用程序的性能和用户体验。同时,它也为前端开发提供了更大的灵活性和可扩展性,适应了不断变化的业务需求和技术发展。
|
1月前
|
缓存 监控
webpack 提高构建速度的方式
【10月更文挑战第23天】需要根据项目的具体情况和需求,综合运用这些方法,不断进行优化和改进,以达到最佳的构建速度和效果。同时,随着项目的发展和变化,还需要持续关注和调整构建速度的相关措施,以适应不断变化的需求。
|
1月前
|
存储 缓存 前端开发
利用 Webpack 5 的持久化缓存来提高构建效率
【10月更文挑战第23天】利用 Webpack 5 的持久化缓存是提高构建效率的有效手段。通过合理的配置和管理,我们可以充分发挥缓存的优势,为项目的构建和开发带来更大的便利和效率提升。你可以根据项目的实际情况,结合以上步骤和方法,进一步优化和完善利用持久化缓存的策略,以达到最佳的构建效果。同时,不断探索和实践新的方法和技术,以适应不断变化的前端开发环境和需求。
|
1月前
|
缓存 前端开发 JavaScript
Webpack 4 和 Webpack 5 区别?
【10月更文挑战第23天】随着时间的推移,Webpack 可能会继续发展和演进,未来的版本可能会带来更多的新特性和改进。保持对技术发展的关注和学习,将有助于我们更好地应对不断变化的前端开发环境。
|
1月前
|
缓存 前端开发 JavaScript
webpack 原理
【10月更文挑战第23天】Webpack 原理是一个复杂但又非常重要的体系。它通过模块解析、依赖管理、加载器和插件的协作,实现了对各种模块的高效打包和处理,为现代前端项目的开发和部署提供了强大的支持。同时,通过代码分割、按需加载、热模块替换等功能,提升了应用程序的性能和用户体验。随着前端技术的不断发展,Webpack 也在不断演进和完善,以适应不断变化的需求和挑战。
|
2月前
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
6月前
|
缓存 JavaScript 前端开发
探讨如何通过一系列优化策略来提升TypeScript与Webpack的构建性能。
【6月更文挑战第11天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(如关闭不必要的类型检查)和webpack.config.js选项,启用Webpack缓存,实现增量构建,代码拆分和懒加载。通过这些方法,可以提升构建速度,提高开发效率。
79 0
|
3月前
|
JavaScript 前端开发
手写一个简易bundler打包工具带你了解Webpack原理
该文章通过手写一个简易的打包工具bundler,帮助读者理解Webpack的工作原理,包括模块解析、依赖关系构建、转换源代码以及生成最终输出文件的整个流程。
|
4月前
|
缓存 前端开发 JavaScript
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
161 1