MST
星途 面试题库

面试题:Webpack使用DllPlugin时如何优化配置

假设你在一个大型前端项目中使用Webpack的DllPlugin来提升打包速度,现有一些依赖库经常变动,一些相对稳定,请问你会如何优化DllPlugin的配置,以平衡打包速度与缓存更新的效率?
17.9万 热度难度
前端开发Webpack

知识考点

AI 面试

面试题答案

一键面试
  1. 分离变动与稳定依赖
    • 将经常变动的依赖库和相对稳定的依赖库分别配置不同的dll文件。例如,对于稳定的库像reactreact - dom等,创建一个vendor.dll.js。对于经常变动的库,比如一些业务特定且频繁更新的ui组件库,创建一个business - ui.dll.js
    • webpack.dll.conf.js文件中分别配置:
const path = require('path');
const webpack = require('webpack');

// 稳定依赖配置
const vendorConfig = {
  entry: {
    vendor: ['react','react - dom']
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, 'dist', '[name].manifest.json'),
      name: '[name]_library'
    })
  ]
};

// 变动依赖配置
const businessUiConfig = {
  entry: {
    'business - ui': ['your - business - ui - library']
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, 'dist', '[name].manifest.json'),
      name: '[name]_library'
    })
  ]
};

module.exports = [vendorConfig, businessUiConfig];
  1. 优化缓存策略
    • 稳定依赖:由于稳定依赖变动少,可在html - webpack - plugin等插件配置中设置较长的缓存时间,比如在webpack.prod.conf.js中配置html - webpack - plugin
const HtmlWebpackPlugin = require('html - webpack - plugin');
module.exports = {
  //...其他配置
  plugins: [
    new HtmlWebpackPlugin({
      //...其他配置
      cache: true,
      minify: {
        //...压缩配置
      },
      chunks: ['vendor'],
      hash: true // 这里的hash用于更新缓存,由于vendor变动少,基本不会触发缓存更新
    })
  ]
};
  • 变动依赖:对于经常变动的依赖库对应的dll文件,设置较短的缓存时间或者通过一些动态的版本号策略。例如,在构建脚本中每次构建时更新dll文件的版本号,在html - webpack - plugin中配置:
const HtmlWebpackPlugin = require('html - webpack - plugin');
const VERSION = new Date().getTime(); // 每次构建生成新的版本号
module.exports = {
  //...其他配置
  plugins: [
    new HtmlWebpackPlugin({
      //...其他配置
      cache: false,
      minify: {
        //...压缩配置
      },
      chunks: ['business - ui'],
      hash: true,
      version: VERSION // 通过版本号更新缓存
    })
  ]
};
  1. 增量构建
    • 使用webpack - bundle - analyzer等工具分析依赖库的变化,对于稳定依赖库如果检测到没有变化,跳过其dll的重新构建。可以编写自定义脚本,在构建前对比dll文件的内容哈希值或者时间戳,如果未改变则不再执行稳定依赖库的dll构建步骤。例如:
const fs = require('fs');
const crypto = require('crypto');
const path = require('path');

const vendorDllPath = path.join(__dirname, 'dist', 'vendor.dll.js');
const lastHashPath = path.join(__dirname, 'last - vendor - hash.txt');

// 计算当前vendor.dll.js的哈希值
const currentHash = crypto.createHash('sha256').update(fs.readFileSync(vendorDllPath)).digest('hex');

// 读取上次保存的哈希值
let lastHash;
try {
  lastHash = fs.readFileSync(lastHashPath, 'utf8').trim();
} catch (e) {
  lastHash = null;
}

if (lastHash === currentHash) {
  // 哈希值相同,跳过vendor.dll.js的构建
  console.log('Vendor DLL has not changed, skipping build.');
} else {
  // 哈希值不同,执行构建
  // 这里执行webpack构建命令
  require('child_process').execSync('webpack --config webpack.dll.conf.js --env.vendor', { stdio: 'inherit' });
  // 保存当前哈希值
  fs.writeFileSync(lastHashPath, currentHash);
}
  1. 监控依赖变化
    • 使用工具如npm - check - updates定期检查依赖库的版本更新情况。在项目脚本中添加命令,例如npm run check - deps,执行该命令可查看哪些依赖库有新版本,对于稳定依赖库如果有更新,谨慎评估后再进行更新,以减少不必要的dll构建。同时,对于变动依赖库,及时更新并重新构建其对应的dll文件。