前端打包优化相关 Webpack

前端打包优化相关 Webpack

打包时间的优化(基于 Vue CLI 4 + Webpack 5)

1. Webpack 配置减少打包时间

1.1 对 JS 配置:排除 node_modulessrc 中的打包内容

在开发环境下,修改 Webpack 的 JS 规则,排除 /node_modulessrc 目录中的 JavaScript 文件。这意味着 node_modulessrc 目录中的 JavaScript 文件不会经过该规则定义的加载器处理(如 Babel 转译、ESLint 检查等)。

javascript 复制代码
chainWebpack: (config) => {
  //  //编译时将项目的版本号作为一个全局常量ProjectVersion注入到代码中
  config.plugin('define').tap((args) => {
    args[0].ProjectVersion = JSON.stringify(ProjectVersion);
    return args;
  });

  // 判断当前环境是否为开发环境
  if (process.env.NODE_ENV === 'development') {
    // 配置模块规则
    config.module
      .rule('js')
      .exclude.add(resolve('/node_modules'))
      .add(resolve('src'));
  }
};
1.2 创建 DLL 配置文件,对第三方插件提前打包到本地
1.2.1 配置打包 DLL 文件
javascript 复制代码
const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'production', // 设置为生产模式
  entry: {
    // 将第三方库分组打包
    vue: ['vue', 'vue-router', 'vuex'],
    elementUI: ['element-ui'],
    axios: ['axios'],
    lodash: ['lodash'],
  },
  output: {
    path: path.resolve(__dirname, 'dll'), // 输出目录
    filename: '[name].dll.js', // 输出文件名
    library: '[name]_library', // 全局变量名
  },
  plugins: [
    // 生成 manifest 文件
    new webpack.DllPlugin({
      name: '[name]_library', // 需要与 output.library 一致
      path: path.resolve(__dirname, 'dll/[name]-manifest.json'), // manifest 文件路径
    }),
  ],
};

执行命令生成 DLL 文件:

bash 复制代码
npx webpack --config webpack.dll.config.js
1.2.2 配置打包文件使用 DLL 文件并插入到模板中
javascript 复制代码
configureWebpack: (config) => {
  config.plugins.push(
    // 引入分片的 DLL 文件
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname, 'public/dll/vue-manifest.json')),
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname, 'public/dll/axios-manifest.json')),
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname, 'public/dll/elementGui-manifest.json')),
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname, 'public/dll/vueBaiduMap-manifest.json')),
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname, 'public/dll/glodonTinymce-manifest.json')),
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname, 'public/dll/elementChinaAreaData-manifest.json')),
    }),
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname, 'public/dll/mintUi-manifest.json')),
    }),

    // 将分片的 DLL 文件添加到 HTML 模板中
    new AddAssetHtmlPlugin([
      {
        filepath: path.resolve(__dirname, 'public/dll/vue.dll.js'),
        publicPath: process.env.VUE_APP_PUBLIC_PATH, // 根据项目路径调整
      },
      {
        filepath: path.resolve(__dirname, 'public/dll/axios.dll.js'),
        publicPath: process.env.VUE_APP_PUBLIC_PATH,
      },
      {
        filepath: path.resolve(__dirname, 'public/dll/vueBaiduMap.dll.js'),
        publicPath: process.env.VUE_APP_PUBLIC_PATH,
      },
      {
        filepath: path.resolve(__dirname, 'public/dll/elementGui.dll.js'),
        publicPath: process.env.VUE_APP_PUBLIC_PATH,
      },
      {
        filepath: path.resolve(__dirname, 'public/dll/glodonTinymce.dll.js'),
        publicPath: process.env.VUE_APP_PUBLIC_PATH,
      },
      {
        filepath: path.resolve(__dirname, 'public/dll/elementChinaAreaData.dll.js'),
        publicPath: process.env.VUE_APP_PUBLIC_PATH,
      },
      {
        filepath: path.resolve(__dirname, 'public/dll/mintUi.dll.js'),
        publicPath: process.env.VUE_APP_PUBLIC_PATH,
      },
    ])
  );
},
1.3 开启多线程打包

使用 thread-loader 可能会达不到效果,因为开启多线程也需要时间。

javascript 复制代码
// 开启多线程打包
config.module
  .rule('vue')
  .use('thread-loader')
  .loader('thread-loader')
  .tap(() => {
    return {
      workers: os.cpus().length,
    };
  })
  .before('vue-loader');
1.4 删除无用的插件配置,去掉 sourceMap
javascript 复制代码
chainWebpack: (config) => {
  // 删除一些无用插件
  config.plugins.delete('friendly-errors');
  config.devtool = false; // eval|none source-map hidden-source-map  // 不生成 sourceMap 源代码,减少体积,加快打包速度
};
1.5 删除 console.log(生产环境),配置压缩 JS 和 CSS
javascript 复制代码
// vue.config.js
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  configureWebpack: {
    optimization: {
      minimize: true, // 启用压缩
      minimizer: [
        new TerserPlugin({
          terserOptions: {
            compress: {
              drop_console: true, // 删除 console.log
              pure_funcs: ['console.log'], // 只删除 console.log
            },
            format: {
              comments: false, // 删除注释
            },
          },
          extractComments: false, // 不提取注释到单独文件
        }),
        new CssMinimizerPlugin({
          minimizerOptions: {
            preset: [
              'default',
              {
                discardComments: { removeAll: true }, // 删除所有注释
              },
            ],
          },
        }),
      ],
    },
  },
};

2. 如何减少 Webpack 打包体积

2.1 按需加载

按需加载可以减少初始加载的代码量,提升页面加载速度。

2.2 Scope Hoisting

Scope Hoisting 会分析出模块之间的依赖关系,尽可能将打包出来的模块合并到一个函数中,减少函数声明和闭包的开销。

2.3 Tree Shaking

Tree Shaking 会去除没有引用的代码,减少打包体积。


通过以上优化措施,可以有效减少 Webpack 打包时间和体积,提升项目性能。

相关推荐
H5css�海秀6 小时前
今天是自学大模型的第一天(sanjose)
后端·python·node.js·php
Z兽兽6 小时前
React@18+Vite项目配置env文件
前端·react.js·前端框架
SuniaWang6 小时前
《Spring AI + 大模型全栈实战》学习手册系列 · 专题六:《Vue3 前端开发实战:打造企业级 RAG 问答界面》
java·前端·人工智能·spring boot·后端·spring·架构
A_nanda7 小时前
根据AI提示排查vue前端项目
前端·javascript·vue.js
happymaker06267 小时前
web前端学习日记——DAY05(定位、浮动、视频音频播放)
前端·学习·音视频
~无忧花开~7 小时前
React状态管理完全指南
开发语言·前端·javascript·react.js·前端框架
LegendNoTitle7 小时前
计算机三级等级考试 网络技术 选择题考点详细梳理
服务器·前端·经验分享·笔记·php
@大迁世界8 小时前
1.什么是 ReactJS?
前端·javascript·react.js·前端框架·ecmascript
BJ-Giser8 小时前
Cesium 基于EZ-Tree的植被效果
前端·可视化·cesium
王码码20359 小时前
Flutter for OpenHarmony:Flutter 三方库 algoliasearch 毫秒级云端搜索体验(云原生搜索引擎)
android·前端·git·flutter·搜索引擎·云原生·harmonyos