vue-cli3使用DllPlugin优化webpack打包性能

本文主要介绍两个插件的使用,DllPlugin 和 DllReferencePlugin,使用DllPlugin和DllReferencePlugin提取公共插件提升打包效率。

一、介绍

核心:将静态资源文件(运行依赖包)与业务代码源文件分开打包,先使用 DllPlugin 给静态资源打包,再使用 DllReferencePlugin 让源文件引用资源文件。

在使用webpack进行打包时候,对于依赖的第三方库,比如vue,vuex等这些不会修改的依赖,我们可以让它和我们自己编写的代码分开打包,这样做的好处是每次更改我本地代码的文件的时候,webpack只需要打包我项目本身的文件代码,而不会再去编译第三方库,那么第三方库在第一次打包的时候只打包一次,以后只要我们不升级第三方包的时候,那么webpack就不会对这些库去打包,这样的可以快速的提高打包的速度。因此为了解决这个问题,DllPluginDllReferencePlugin插件就产生了。

那么对于目前webpack社区来讲,我们希望和自己编写的代码分离开的话,webpack社区提供了2种方案:

1、CommonsChunkPlugin 2、DLLPlugin CommonsChunkPlugin 插件每次打包的时候还是会去处理一些第三方依赖库,只是它能把第三方库文件和我们的代码分开掉,生成一个独立的js文件。但是它还是不能提高打包的速度。在vue3.x的vue.config配置文件中我们可以从官网找到optimization的配置,此配置很实用,具体的操作这里就不介绍,可官网查看optimization配置

DLLPlugin 它能把第三方库代码分离开,并且每次文件更改的时候,它只会打包该项目自身的代码。所以打包速度会更快。

DLLPlugin 这个插件是在一个额外独立的webpack设置中创建一个只有dll的bundle,也就是说我们在项目根目录下除了有webpack.config.js,还会新建一个webpack.dll.config.js文件。webpack.dll.config.js作用是把所有的第三方库依赖打包到一个bundle的dll文件里面,还会生成一个名为 manifest.json文件。 该manifest.json的作用是用来让 DllReferencePlugin 映射到相关的依赖上去的。

DllReferencePlugin 这个插件是在webpack.config.js中使用的,该插件的作用是把刚刚在webpack.dll.config.js中打包生成的dll文件引用到需要的预编译的依赖上来。什么意思呢?就是说在webpack.dll.config.js中打包后比如会生成 vendor.dll.js文件和vendor-manifest.json文件,vendor.dll.js文件包含所有的第三方库文件,vendor-manifest.json文件会包含所有库代码的一个索引,当在使用webpack.config.js文件打包DllReferencePlugin插件的时候,会使用该DllReferencePlugin插件读取vendor-manifest.json文件,看看是否有该第三方库。vendor-manifest.json文件就是有一个第三方库的一个映射而已。

所以说 第一次使用 webpack.dll.config.js 文件会对第三方库打包,打包完成后就不会再打包它了,然后每次运行 webpack.config.js文件的时候,都会打包项目中本身的文件代码,当需要使用第三方依赖的时候,会使用 DllReferencePlugin插件去读取第三方依赖库。所以说它的打包速度会得到一个很大的提升

二、DllPlugin配置

配置DllPluginDllReferencePlugin成功后,项目目录结构如下: 项目中主要引入dependencies中第三方插件主要要有axioselement-plusvuevue-routervuex,在插件没有变化的话,使用commonChunkPlugin插件打包出来的vendor.js文件基本不会有变化,我们完全可以把此处使用到的代码提取出来,这样打包就能减少很多时间。 在此之前,我们先执行下npm run build看看打包出的文件大小和时长。 可以看出,使用commonChunkPlugin打包项目代码花了大概6075ms ,可以发现项目在引入少量插件情况下,就需要怎么长时间,所以对大项目还是很有必要对打包优化,接下来我们对项目进行改造,使用DllPluginDllReferencePlugin,看看在同等引入第三方插件情况下,到底能减少多少时间?

build目录下新建webpack.dll.conf.js文件,里面内容如下:

javascript 复制代码
const path = require("path");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
/* 将特定的类库提前打包然后引入,不但能够极大减少打包时间,
也实现了将公共代码抽离成单独文件的优化方案,可以很大程度的减小打包之后的文件体积。 */
// dll文件存放的目录(建议存放到public中)
const dllPath = "./public/vendor";
module.exports = {
  // 如果这些类库有版本更新了(一般很少更新),就需要重新执行 npm run dll 打包类库,再执行 npm run build 打包项目上线
  // 这里用 vendor 作为 key 值表示后文用到的 [name] ,后续生成的打包文件就为 vendor-manifest.json  vendor.dll.js
  entry: {
    vendor: ["vue", "vuex", "vue-router", "element-plus", "axios"],
  },
  output: {
    filename: "[name].dll.js",  // 打包后的文件名 vendor.dll.js
    path: path.resolve(__dirname, dllPath), // 打包后文件输出的位置,放到项目根目录的 public/vendor 下
    // vendor.dll.js 中暴露出的全局变量名,主要是给 DllPlugin 中的 name 使用。
    // 所以这里需要和 webpack.DllPlugin 中的 name: '[name]_library', 保持一致。
    library: "[name]_[hash]",
  },
  plugins: [
    // 清除之前的dll文件
    new CleanWebpackPlugin(),
    // manifest.json描述动态链接库包含了哪些内容
    new webpack.DllPlugin({
      // 和 output.library 保持一致即可
      name: "[name]_[hash]",
      path: path.join(__dirname, dllPath, "[name]-manifest.json"),
      // manifest 文件中请求的上下文,默认为本文件的上下文
      context: process.cwd(),
    }),
  ],
};
​

webpack.dll.conf.js文件使用了clean-webpack-plugin插件,先通过npm命令安装:

复制代码
npm install -D clean-webpack-plugin

下载成功后,可以在package.json文件下devDependencies看到对应模块。

package.json文件添加npm run dll命令如下:

json 复制代码
"dll": "webpack --config ./webpack.dll.conf.js"

运行npm run dll命令结果如下:

在public文件夹下的vendor文件夹发现有个vendor.dll.js、vendor-mainfest.json文件,说明已经执行成功了。

可以看出,使用DllPlugin打包项目代码花了大概2023ms

三、DllReferencePlugin配置

直接在根目录下的vue.config.js文件进行配置,里面内容如下:

javascript 复制代码
const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
const path = require('path');
// 这些代码就是dll优化的代码
const dllReference = (config) => {
  config.plugin('vendorDll')
    .use(webpack.DllReferencePlugin, [{
      context: __dirname,
      manifest: require('./public/vendor/vendor-manifest.json')
    }]);
  // 这里是把相关文件引用入到html模板中
  config.plugin('addAssetHtml')
    .use(AddAssetHtmlPlugin, [
      [
        {
          filepath: require.resolve(path.resolve(__dirname, 'public/vendor/vendor.dll.js')),
          outputPath: 'vendor',
          publicPath: 'vendor'
        }
      ]
    ])
    .after('html')
};
​
module.exports = {
  chainWebpack: (config) => {
    if (process.env.NODE_ENV === 'production') { // 这里区分下,只有生产环境才需要用到
      dllReference(config)
    }
  }
};
​

vue.config.js文件使用了add-asset-html-webpack-plugin插件,先通过npm命令安装:

csharp 复制代码
npm install -D add-asset-html-webpack-plugin

下载成功后,可以在package.json文件下devDependencies看到对应模块。

为社么要使用改插件?就是解决以前在vue-cli2项目需要单独对每个html模板添加script标签,引入vendor.dll.js文件

xml 复制代码
<script type='text/javascript' src='./public/vendor/vendor.dll.js'></script>

和在.conf.js文件去掉CommonChunkPlugin生成vendor.js和manifest.js文件的配置注释或者删除。

ruby 复制代码
// new webpack.optimize.CommonsChunkPlugin({
//   name: 'vendor',
//   minChunks (module) {
//     // any required modules inside node_modules are extracted to vendor
//     return (
//       module.resource &&
//       /.js$/.test(module.resource) &&
//       module.resource.indexOf(
//         path.join(__dirname, '../node_modules')
//       ) === 0
//     )
//   }
// }),
​
// new webpack.optimize.CommonsChunkPlugin({
//   name: 'manifest',
//   minChunks: Infinity
// }),

然后添加plugins:

css 复制代码
  new webpack.DllReferencePlugin({
    manifest: require(path.resolve(__dirname, './.public/vendor/vendor-manifest.json'))
  }),

其实就是手动在页面引入第三方插件,为了方便使用,可以在vue.config.js配置成自动化注入。

到这里就针对DllPlugin 和 DllReferencePlugin所有配置就结束了,直接执行npm run build,会生成一个dist文件,同时发现编译打包速度比以前快很多,刚开始6075ms 优化后为2023ms ,差不多提升了一半。

四、参考资料

vue-cli3中webpack.dll打包优化

webpack使用DllPlugin和DllReferencePlugin提取公共插件提升打包效率

使用DllPlugin优化webpack打包性能(基于vue-cli)

vue webpack打包优化操作技巧

相关推荐
zhougl9961 小时前
html处理Base文件流
linux·前端·html
花花鱼1 小时前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_1 小时前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo2 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)3 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之4 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端4 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡4 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木5 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!6 小时前
优选算法系列(5.位运算)
java·前端·c++·算法