前端打包优化相关 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 打包时间和体积,提升项目性能。

相关推荐
Fantasywt3 小时前
THREEJS 片元着色器实现更自然的呼吸灯效果
前端·javascript·着色器
IT、木易3 小时前
大白话JavaScript实现一个函数,将字符串中的每个单词首字母大写。
开发语言·前端·javascript·ecmascript
张拭心5 小时前
2024 总结,我的停滞与觉醒
android·前端
念九_ysl5 小时前
深入解析Vue3单文件组件:原理、场景与实战
前端·javascript·vue.js
Jenna的海糖5 小时前
vue3如何配置环境和打包
前端·javascript·vue.js
星之卡比*6 小时前
前端知识点---库和包的概念
前端·harmonyos·鸿蒙
灵感__idea6 小时前
Vuejs技术内幕:数据响应式之3.x版
前端·vue.js·源码阅读
烛阴6 小时前
JavaScript 构造器进阶:掌握 “new” 的底层原理,写出更优雅的代码!
前端·javascript
Alan-Xia6 小时前
使用jest测试用例之入门篇
前端·javascript·学习·测试用例
浪遏6 小时前
面试官😏 :文本太长,超出部分用省略号 ,怎么搞?我:🤡
前端·面试