一招教会你提高vue-cli3项目的打包和编译速度

一、背景

由于旧项目是用vue-cli3脚手架搭建,随着项目代码不断增加,webpack每次热更新都需要编译很久,同时打包构建所需时间也增加了不少,鉴于升级webpack版本会出现各自意想不到的坑,所以决定通过优化webpack配置来提高项目的编译和构建速度,话不多说,开整!!!!!

二、项目环境

本次优化的项目的环境是:node版本14.17.0 npm版本6.14.13

js 复制代码
package.json 限定了node和npm的版本
"engines": {
    "node": ">=14.17.0",
    "npm": ">=6.14.13"
  },

三、使用Happypack插件

使用该插件的主要目的是因为该插件将任务分解到多个子进程中去并行处理,从而减少总的构建时间。使用配置如下:

js 复制代码
vue.config.js文件
安装happypack npm install happypack -D
const Happypack = require('happypack')
configureWebpack:{
// 该配置可以提高25%左右的速度
 new Happypack({
      loaders: ['babel-loader', 'vue-loader', 'url-loader'],
      cache: true,
      threads: 10 // 线程数取决于你电脑性能的好坏,好的电脑建议开更多线程
    })
}

四、使用文件压缩插件 compression-webpack-plugin

该插件的主要作用是压缩文件,可以降低dist包文件大小,配置如下:

js 复制代码
// 需要压缩的文件
vue.config.js文件
安装compression-webpack-plugin npm install compression-webpack-plugin -D
// 压缩,可以将dist文件由20M压缩到3M
const CompressionPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i
configureWebpack:{
 plugins: [
      new CompressionPlugin({
      test: productionGzipExtensions, // 需要压缩的文件正则
      threshold: 10240, // 文件大小大于这个值时启用压缩
      deleteOriginalAssets: true // 压缩后保留原文件
    })
  ]
}

五、使用dll

该插件是用于打包一些版本基本不怎么变的第三方库,然后引入到index.html文件里,它的主要作用是缓存和复用代码,以提高构建速度和效率。使用DLL插件可以避免重复打包和编译那些没有改变的或者变化不大的代码,从而提高构建速度和效率。DLL插件的使用可以显著提高大型项目的构建速度,同时也可以减少打包文件的大小。具体使用方式如下

js 复制代码
安装 npm install --save-dev webpack-dll-plugin
安装 html-include-assets-plugin 
// 开启dll
const dllHelper = require('./dllHelper');
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin');
const HtmlIncludeAssetsPlugin = require('html-include-assets-plugin');  
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i
configureWebpack:{
 plugins: [
      // 开启dll,构建时间可以减短,比HardSourceWebpackPlugin更快,但是每次都需要执行dll命令
    ...dllHelper.genDllReferences(),
    new HtmlIncludeAssetsPlugin({
     assets: dllHelper.loadDllAssets(), 
    append: false
    })
  ]
}
js 复制代码
新建一个webpack.dll.conf.js文件
安装 clean-webpack-plugin
const path = require('path')
const webpack = require('webpack')
const  CleanWebpackPlugin = require('clean-webpack-plugin')

// dll文件存放的目录
const dllPath = 'public/vendor'

module.exports = {
  entry: {
    // 需要提取的库文件
    vue: ["vue", "vue-router", "vuex"],
    plugin: ['vxe-table','vxe-table-plugin-antd','ali-oss'],
    ui: ['ant-design-vue'],
  },
  output: {
    path: path.join(__dirname, dllPath),
    filename: '[name].dll.js',
    // vendor.dll.js中暴露出的全局变量名
    // 保持与 webpack.DllPlugin 中名称一致
    library: '[name]_[hash]'
  },
  plugins: [
    // 清除之前的dll文件
    new CleanWebpackPlugin(),
    // 设置环境变量
    // new webpack.DefinePlugin({
    //   'process.env': {
    //     NODE_ENV: 'production'
    //   }
    // }),
    // manifest.json 描述动态链接库包含了哪些内容
    new webpack.DllPlugin({
      path: path.join(__dirname, dllPath, '[name]-manifest.json'),
      // 保持与 output.library 中名称一致
      name: '[name]_[hash]',
      context: process.cwd()
    })
  ]
}
js 复制代码
新建dllHelper.js 文件

// config/dllHelper.js
const webpack = require('webpack');
const path = require('path');
const fs = require('fs');
const dllConfig = require('./webpack.dll.conf');

// 根据entry生成DllReferencePlugin列表
function genDllReferences() {
  return Object.keys(dllConfig.entry).map(
    name =>
      new webpack.DllReferencePlugin({
        manifest: require(path.join(
          __dirname,
          `./public/vendor/${name}-manifest.json`
        ))
      })
  );

}

// 生成dll文件的静态资源路径
function loadDllAssets() {
  return fs
    .readdirSync(path.resolve(__dirname, 'public/vendor'))
    .filter(filename => filename.match(/.dll.js$/))
    .map(filename => `vendor/${filename}`);
}

module.exports = {
  loadDllAssets,
  genDllReferences
};
构建前,我们需要配置dll命令,执行npm run dll 命令,最终dll文件会插入到index.html文件中
"script":{
 "dll": "webpack -p --progress --config ./webpack.dll.conf.js"
 }

六、使用HardSourceWebpackPlugin,这个插件会比dll要慢一点,主要是设置缓存,提高二次构建的速度

js 复制代码
安装HardSourceWebpackPlugin npm install HardSourceWebpackPlugin -D
// 缓存
const HardSourceWebpackPlugin = 
    require('hard-source-webpack-plugin');
configureWebpack:{
 plugins: [
     // 设置缓存,缺陷在于会占用本地磁盘空间,比dll慢,两个一起用比dll还慢一点点
new HardSourceWebpackPlugin({
  //设置缓存目录的路径
  //相对路径或者绝对路径
  cacheDirectory: 'node_modules/.cache/hard-source/[confighash]',
  //构建不同的缓存目录名称
  //也就是cacheDirectory中的[confighash]值
  configHash: function(webpackConfig) {
    return require('node-object-hash')({sort: false}).hash(webpackConfig);
  },
  //环境hash
  //当loader、plugin或者其他npm依赖改变时进行替换缓存
  environmentHash: {
    root: process.cwd(),
    directories: [],
    files: ['package-lock.json', 'yarn.lock'],
  },
  //自动清除缓存
  cachePrune: {
    //缓存最长时间(默认2天)
    maxAge: 2 * 24 * 60 * 60 * 1000,
    //所有的缓存大小超过size值将会被清除
    //默认50MB
    sizeThreshold: 50 * 1024 * 1024
  },
}),
  ]
}

七、代码分割

js 复制代码
chainWebpack: (config) => {
 //代码分割
    config.optimization.splitChunks({
      //chunks: 'all'
      cacheGroups: {
        vendor: {//第三方库抽离
            chunks: 'all',
            test: /node_modules/,
            name: 'vendor',
            minChunks: 1,//在分割之前,这个代码块最小应该被引用的次数
            maxInitialRequests: 5,
            minSize: 0,//大于0个字节
            priority: 100//权重
        },
        common: {  //公用模块抽离
            chunks: 'all',
            test: /[\\/]src[\\/]js[\\/]/,
            name: 'common',
            minChunks: 2,//在分割之前,这个代码块最小应该被引用的次数
            maxInitialRequests: 5,
            minSize: 0,//大于0个字节
            priority: 60
        },
        styles: { //样式抽离
            name: 'styles',
            test: /\.(sa|sc|c)ss$/,
            chunks: 'all',
            enforce: true
        },
        runtimeChunk: {
            name: 'manifest'
        }
    }

    })
 }

八、配置一些loader配置

js 复制代码
configureWebpack:{
module: {
//如果一些第三方模块没有AMD/CommonJS规范版本,可以使用 noParse 来标识这个模块,
//这样 Webpack 会引入这些模块,但是不进行转化和解析,从而提升 Webpack 的构建性能 ,例如:jquery 、lodash。
      noParse: /^(lodash|moment|xe-utils|xlsx|ali-oss)$/,
      rules: [
        {
          test: /\.vue$/,
          loader: 'vue-loader',
          options: {
          // 开启缓存
           cacheDirectory: true
          }
        },
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env']
            }
          }
        },
        
      ]
   }
}

九、开启文件变化监听,速度提升不算很大,在大型项目比较有用

js 复制代码
  chainWebpack: (config) => {
 if (process.env.NODE_ENV !== 'production') {  
        config.watch(true)
        config.watchOptions(  
          {  
            // 排除监听文件
              ignored: /node_modules/,
            // 在监听到文件变化后等待一段时间再执行编译
             aggregateTimeout: 300, // 300ms 
            // 开启轮询
            poll: 100
          } 
        )
      }
      }

总结:以上配置可以按需选择,并不一定所有配置都需要用上,选择你觉得对你项目效果比较明显的即可。

相关推荐
苹果酱05673 小时前
Golang的文件加密技术研究与应用
java·vue.js·spring boot·mysql·课程设计
vvw&3 小时前
如何在 Ubuntu 22.04 上安装 Caddy Web 服务器教程
linux·运维·服务器·前端·ubuntu·web·caddy
AH_HH5 小时前
如何学习Vue设计模式
vue.js·学习·设计模式
落日弥漫的橘_5 小时前
npm run 运行项目报错:Cannot resolve the ‘pnmp‘ package manager
前端·vue.js·npm·node.js
梦里小白龙5 小时前
npm发布流程说明
前端·npm·node.js
No Silver Bullet5 小时前
Vue进阶(贰幺贰)npm run build多环境编译
前端·vue.js·npm
破浪前行·吴6 小时前
【初体验】【学习】Web Component
前端·javascript·css·学习·html
猛踹瘸子那条好腿(职场发疯版)6 小时前
Vue.js Ajax(vue-resource)
vue.js·ajax·okhttp
泷羽Sec-pp6 小时前
基于Centos 7系统的安全加固方案
java·服务器·前端
IT 古月方源6 小时前
GRE技术的详细解释
运维·前端·网络·tcp/ip·华为·智能路由器