webpack(四)-构建速度性能优化

520 阅读3分钟

DllPlugin插件打包第三⽅类库 优化构建性能

项⽬中引⼊了很多第三方库,这些库在很⻓的一段时间内,基本不会更新,打包的 时候分开打包来提升打包速度,而DllPlugin动态链接库插件, 其原理就是把⽹页依赖 的基础模块抽离出来打包到dll⽂件中,当需要导⼊的模块存在于某个dll中时,这个 模块不再被打包,⽽是去dll中获取。

Dll动态链接库

.dll⽂件称为动态链接库,在windows系统会经常看到.

动态链接库只需要被编译一次,项⽬中用到的第三方模块,很稳定,例如 react,react-dom,只要没有升级的需求

webpack已经内置了对动态链接库的支持

  • DllPlugin:⽤于打包出⼀个单独的动态链接库文件
  • DllReferencePlugin:⽤于在主要的配置⽂件中引⼊DllPlugin插件打包好的动态链 接库文件

我们在 index.js 中使⽤了第三方库 react 、 react-dom ,接下来,我们先对这 两个库先进⾏行打包。

const path = require("path");
const { DllPlugin } = require("webpack");
module.exports = {
  mode: "development",
  entry: {
    react: ["react", "react-dom"], //! node_modules?
    lodash: ['lodash'] //! node_modules?
  },
  output: {
    path: path.resolve(__dirname, "./dll"),
    filename: "[name].dll.js",
    library: "[name]"
  },
  plugins: [
    new DllPlugin({
        // manifest.json文件的输出位置
        path: path.join(__dirname, "./dll", "[name]-manifest.json"),
        // 定义打包的公共vendor⽂件对外暴露的函数名
        // 必须和library的name保持一致
        name: "[name]"
    })
  ]
};
 

接下来怎么使用呢?

要给web项⽬目构建介入动态链接库,需要完成以下事情:

  • 将⽹页依赖的基础模块抽离,打包到单独的动态链接库,一个动态链接库是可以 包含多个模块的。

  • 当需要导⼊的模块存在于某个动态链接库中时,不要再次打包,直接使用构建好的动态链接库即可。

 
##webpack.dev.config.js
new DllReferencePlugin({
    manifest: require("./dll/react-manifest.json")
}),

此时 在dist目录中会多出来一个react.dll.js

⻚面依赖的所有动态链接库都需要被加载。

推荐使用add-asset-html-webpack-plugin插件加载动态链接库

 webpack.config.js
new AddAssetHtmlWebpackPlugin({
    filepath: path.resolve(__dirname, '../dll/react.dll.js') // 对应的dll ⽂件路径 
}),

HardSourceWebpackPlugin

 
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
const plugins = [
  new HardSourceWebpackPlugin()
]

也是把第三方包放在物理硬盘中

使用happypack并发执⾏任务

运⾏在 Node.之上的Webpack是单线程模型的,也就是说Webpack需要⼀个一个地处 理任务,不能同时处理多个任务。 Happy Pack 就能让Webpack做到这一点,它将任 务分解给多个⼦进程去并发执行,子进程处理完后再将结果发送给主进程。从⽽发 挥多核 CPU 电脑的威力

 npm i -D happypack
  var happyThreadPool = HappyPack.ThreadPool({ size: 5 });
  //const happyThreadPool = HappyPack.ThreadPool({ size:
os.cpus().length })
// webpack.config.js
rules: [ {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
            {
                loader: "happypack/loader?id=babel"
            }
        ]
      },
      {
        test: /\.css$/,
        include: path.resolve(__dirname, "./src"),
        use: ["happypack/loader?id=css"]
        },
    ]
    //在plugins中增加 plugins:[
    new HappyPack({
        // ⽤唯一的标识符id,来代表当前的HappyPack是⽤来处理一类特定的文件
        id:'babel',
        // 如何处理.js文件,⽤法和Loader配置中一样 
        loaders:['babel-loader?cacheDirectory'],
        threadPool: happyThreadPool,
    }),
    new HappyPack({
      id: "css",
      loaders: ["style-loader", "css-loader"]
    }),
]
 

happypack和minicssextractplugin一起使用会有问题

参考链接1

参考链接2