likes
comments
collection
share

【前端-调优】vue-cli前端工程webpack启动构建打包优化记录-6分钟至29秒

作者站长头像
站长
· 阅读数 23

vue-cli前端工程webpack优化记录

文章已收录至lichong.work,转载请注明原文链接。 ps:欢迎关注公众号“Fun肆编程”或添加我的私人微信交流经验🤝

优化原因

  1. 开发环境启动时间耗时长。公司电脑配置一般,启动一下需要一两分钟。
  2. 持续构建环境耗时长,打包慢。

优化效果

优化前

启动时间:17.37秒

【前端-调优】vue-cli前端工程webpack启动构建打包优化记录-6分钟至29秒

Jenkins打包时间:6分钟

【前端-调优】vue-cli前端工程webpack启动构建打包优化记录-6分钟至29秒

优化后

启动时间:1.36秒

【前端-调优】vue-cli前端工程webpack启动构建打包优化记录-6分钟至29秒

服务器打包时间:29秒

【前端-调优】vue-cli前端工程webpack启动构建打包优化记录-6分钟至29秒

优化步骤

基础环境

【前端-调优】vue-cli前端工程webpack启动构建打包优化记录-6分钟至29秒

优化思路

简单讲就两点:1.缓存,2.利用多线程

webpack5是直接提供了开启文件缓存的简单配置,如果你还在用4及以下版本的webpack就需要手动引入hard-source-webpack-plugincache-loader插件去手动配置了

步骤

引入speed-measure-webpack-plugin(统计编译时间插件)、thread-loader(多线程编译):

npm install -D speed-measure-webpack-plugin thread-loader

具体步骤:

  • 开启编译缓存,相关代码:

    configureWebpack: {
        cache: {
          // 使用文件缓存,加速二次构建
          type: 'filesystem'
        }
      }
    
  • 开启多线程编译,相关代码:

    const { defineConfig } = require('@vue/cli-service');
    const os = require('os');
    // cpu核数
    const threads = os.cpus().length;
    console.log('编译线程数', threads);
    const vueConfig = defineConfig({
      chainWebpack: (config) => {
        // 多核编译
        config.module
          .rule('vue')
          .use('thread-loader')
          .loader('thread-loader')
          .options({
            workers: threads
          })
          .end();
        config.module
          .rule('js')
          .use('thread-loader')
          .loader('thread-loader')
          .options({
            workers: threads
          })
          .end();
        }
      }
    });
    
  • vue-cli已经自带了terser插件,所以我们需要通过chainwebpack去修改,让插件多线程编译,相关代码:

    config.optimization.minimizer('terser').tap((args) => {
            args[0].parallel = threads;
            args[0].terserOptions.compress.warnings = true;
            args[0].terserOptions.compress.drop_debugger = true;
            args[0].terserOptions.compress.drop_console = true;
            return args;
          });
    

完整vue.conifg.js

const { defineConfig } = require('@vue/cli-service');
const webpack = require('webpack');
const path = require('path');
const os = require('os');
// 构建时间统计插件
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');

// 开发环境代理的后端地址
const target = 'http://127.0.0.1:8080';
// 打包输出文件夹
const outputDir = 'dist';
// 打包后资源文件存放的目录
const assetsDir = 'static';
// 是否启用ESLint
const lintOnSave = true;
// 是否使用mock数据
const useMock = true;
// 生产环境是否构建source map
const productionSourceMap = false;

// cpu核数
const threads = os.cpus().length;
console.log('编译线程数', threads);

const vueConfig = defineConfig({
  indexPath: 'index.html',
  devServer: {
    host: '0.0.0.0',
    port: 3000,
    hot: true,
    proxy: {
      '/api/*': {
        target,
        secure: false,
        changeOrigin: true
      }
    }
  },
  publicPath: process.env.NODE_ENV === 'production' ? '/api' : '/',
  transpileDependencies: true,
  runtimeCompiler: true,
  lintOnSave,
  assetsDir,
  outputDir,
  productionSourceMap,
  css: {
    sourceMap: true,
    loaderOptions: {
      less: {
        lessOptions: {
          javascriptEnabled: true
        }
      },
      sass: {},
      scss: {}
    }
  },
  chainWebpack: (config) => {
    // 多核编译
    config.module
      .rule('vue')
      .use('thread-loader')
      .loader('thread-loader')
      .options({
        workers: threads
      })
      .end();
    config.module
      .rule('js')
      .use('thread-loader')
      .loader('thread-loader')
      .options({
        workers: threads
      })
      .end();
    if (process.env.NODE_ENV === 'development' && useMock) {
      config
        .plugin('copy-webpack-plugin')
        .use('copy-webpack-plugin')
        .tap((options) => {
          options[0] = {
            patterns: [
              {
                from: path.resolve(__dirname, './mock'),
                to: path.join(__dirname, './', outputDir, assetsDir),
                toType: 'dir',
                force: true
              }
            ]
          };
          return options;
        });
    }
    if (process.env.NODE_ENV === 'production') {
      config.optimization.minimizer('terser').tap((args) => {
        args[0].parallel = threads;
        args[0].terserOptions.compress.warnings = true;
        args[0].terserOptions.compress.drop_debugger = true;
        args[0].terserOptions.compress.drop_console = true;
        return args;
      });
      config.optimization.runtimeChunk(true).splitChunks({
        chunks: 'all',
        // 重复打包问题
        cacheGroups: {
          vendors: {
            // node_modules里的代码
            test: /[\\/]node_modules[\\/]/,
            chunks: 'all',
            priority: 10, // 优先级
            enforce: true
          }
        }
      });
    }
  },
  configureWebpack: {
    cache: {
      // 使用文件缓存,加速二次构建
      type: 'filesystem'
    },
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery'
      }),
      new SpeedMeasurePlugin()
    ]
  }
});

module.exports = vueConfig;

文章已收录至lichong.work,转载请注明原文链接。 ps:欢迎关注公众号“Fun肆编程”或添加我的私人微信交流经验🤝

✨欢迎为耿直少年点赞、关注、收藏!!!