网页优化-DllPlugin

204 阅读1分钟

DllPlugin插件:可以将类库从业务代码中分离出去,其原理是预先将类库文件打包,随后创建一个关联表,在业务代码依赖第三方类库时,会直接去关联表中获取已经打包好的类库文件。

好处: 因为业务代码会常常需要打包上线,而第三方类库基本不会改变,所以每次打包可以跳过这些类库文件,减少不必要的重复打包.

add-asset-html-webpack-plugin插件 index.html中注入多个类库引用

<script defer="defer" type="module" src="/js/vender.dll.js"></script>
  1. 根目录 创建webpack.dll.js

    打包后的 xxx.dll.js 文件放在.dll目录中

    terser-webpack-plugin 删除类库中的log

    new DllPlugin() 创建时配置context 属性,不配置会报错 Uncaught ReferenceError: vendor is not defined

const path = require("path");
const TerserWebpackPlugin = require("terser-webpack-plugin");
const { DllPlugin } = require("webpack"); // 由于 vue-cli 内置了 webpack 所以不需要在 package.json 中声明
const DLL_DIR = path.resolve(__dirname, '.dll')

module.exports = {
  mode: "production",
  entry: {
    vender: ["vue", 'vuex', 'vue-router', 'axios']
  },
  output: {
    path: DLL_DIR,
    filename: "[name].dll.js",
    // 库全局变量的名字,如何暴露模块
    library: "[name]"
  },
  optimization: {
    minimizer: [
      // 删除类库文件中的log
      new TerserWebpackPlugin({
        terserOptions: {
          warnings: false,
          compress: {
            drop_debugger: true,
            drop_console: true
          }
        }
      })
    ]
  },
  plugins: [
    new DllPlugin({
      //必须和全局变量即library名字相同,否则DllPlugin插件找不到第三方库
      name: "[name]",
      context: DLL_DIR,
      path: path.join(DLL_DIR, "/[name].manifest.json")
    })
  ]
};

  1. 生成.dll文件夹,package.json 添加执行命令
"dll": "webpack --config webpack.dll.js",
  1. 配置vue.config.js
const fs = require("fs");
const path = require("path")
const AddAssetHtmlWebpackPlugin = require("add-asset-html-webpack-plugin"); // 给 index.html 注入 dll 生成的链接库
const { DllReferencePlugin } = require("webpack");
const IS_PRODUCTION = process.env.NODE_ENV !== "development"
const DLL_DIR = path.resolve(__dirname, '.dll')

const plugins = [];
// 通过 readdirSync 分析 .dll 目录读取文件名  
// 动态注册 AddAssetHtmlWebpackPlugin 和 webpack.DllReferencePlugin
if (IS_PRODUCTION && fs.existsSync(DLL_DIR)) {
  fs.readdirSync(DLL_DIR).forEach(file => {
    if (/.*\.dll\.js$/.test(file)) {
      plugins.push(
        new AddAssetHtmlWebpackPlugin({
          filepath: path.resolve(DLL_DIR, file),
          outputPath: "js", // 输出路径,相对于默认的输出路径(dist)
          publicPath: "/js" // 引入文件路径 需要修改
        })
      );
    }
    if (/.*\.manifest.json/.test(file)) {
      plugins.push(
        new DllReferencePlugin({
          manifest: path.resolve(DLL_DIR, file)
        })
      );
    }
  });
}

module.exports = {
    ...
    configureWebpack: (config) => {
	config.plugins.push(...plugins)
    }
    ...
}

配置在生产环境中生效, 执行命令 npm run build