美文网首页
2022-04-17

2022-04-17

作者: 姜浩_19强化班 | 来源:发表于2022-04-17 17:00 被阅读0次

happyPack与thread-load

happyPack实现多线程编译

webpack在node中是单线程的,但是在使用webpack编译项目时,loader、plugin需要处理的文件数量很大,webpack单线程处理导致效率低、速度慢,可以使用happyPack来实现多线程工作。

happyPack将不同的loader、plugin工作分配到不同的子线程,在子线程结束完后再推入到主线程中,多线程同时编译,减少编译时间。

基本使用

const path = require('path');

const HappyPack = require('happypack');

module.exports = {

  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'],

      // ... 其它配置项

    }),

    new HappyPack({

      id: 'css',

      // 如何处理 .css 文件,用法和 Loader 配置中一样

      loaders: ['css-loader'],

    }),

    new ExtractTextPlugin({

      filename: `[name].css`,

    }),

  ],

};

loader配置中,全部交给happyPck/loader处理,其后的 id=babel告诉happyPck/loader选择哪个happyPack实例处理文件

plugin中,options中设置的id和loader中使用的id对应。

实例化happyPack时的其他options

threads代表开启几个子进程去处理这一类型的文件,默认是3个,类型必须是整数。

verbose是否允许HappyPack输出日志,默认是true。

threadPool代表共享进程池,即多个HappyPack实例都使用同一个共享进程池中的子进程去处理任务,以防止资源占用过多,相关代码如下:

const HappyPack = require('happypack')

const os = require('os')

//os nodejs os模块提供了一些基本的系统操作函数

const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })

module.exports = {

    ...

        plugins: [

            new HappyPack({

                id: 'js',

                threadPool: happyThreadPool,

                loaders: ['babel-loader?cacheDirectory=true']

            }),

        ]

}

基本原理

在整个 Webpack 构建流程中,最耗时的流程可能就是Loader对文件的转换操作了,因为要转换的文件数据巨多,而且这些转换操作都只能一个个挨着处理。 HappyPack的核心原理就是把这部分任务分解到多个进程去并行处理,从而减少了总的构建时间。

所有需要通过Loader处理的文件都先交给了happypack/loader去处理,收集到了这些文件的处理权后HappyPack就好统一分配了。

每通过new HappyPack()实例化一个HappyPack其实就是告诉HappyPack核心调度器如何通过一系列Loader去转换一类文件,并且可以指定如何给这类转换操作分配子进程。

核心调度器的逻辑代码在主进程中,也就是运行着Webpack的进程中,核心调度器会把一个个任务分配给当前空闲的子进程,子进程处理完毕后把结果发送给核心调度器,它们之间的数据交换是通过进程间通信API实现的。

核心调度器收到来自子进程处理完毕的结果后会通知Webpack该文件处理完毕

thread-load替代happyPack

happyPack的作者不维护了,现在使用thread-load

使用thread-load可以实现将不同编译工作放入不同的工作池中运行。

将thread-load放在其他loader的前面即可,那么在它其后的loader就会单独运行在一个工作池中。

相关文章

网友评论

      本文标题:2022-04-17

      本文链接:https://www.haomeiwen.com/subject/luelertx.html