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

相关推荐
小妖怪的夏天2 分钟前
electron 打包web页面解决跨域问题
前端·javascript·electron
骚饼9 分钟前
Git 命令配置别名、Git命令缩写(Mac版)
前端·git
LoveEate21 分钟前
vue3 el-switch表单联动校验
前端·javascript·vue.js
z_y_j22997043825 分钟前
服务器中更新前端项目
服务器·前端
2301_7976042431 分钟前
d40: vue杂项问题
前端·javascript·vue.js
Mintopia1 小时前
领域适配 AIGC:垂直行业 Web 应用的微调技术实践
前端·javascript·aigc
Mintopia1 小时前
Next.js 内置后端能力扩展 —— 重定向与路由保护
前端·javascript·next.js
IT_陈寒1 小时前
Python 3.12 性能暴增50%!这5个新特性让老项目直接起飞
前端·人工智能·后端
excel2 小时前
JavaScript 中的对象池:复用对象的高效方案
前端
excel2 小时前
Vue实例挂载的过程中发生了什么
前端