侧边栏壁纸
博主头像
uvdream博主等级

一切皆有可能!

  • 累计撰写 37 篇文章
  • 累计创建 21 个标签
  • 累计收到 18 条评论

webpack优化项

uvdream
2021-09-04 / 2 评论 / 14 点赞 / 760 阅读 / 4,250 字
温馨提示:
本文最后更新于 2022-04-08,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

目的:

  • 减小打包后的文件大小
  • 优化webpack打包时间
  • 加快首屏加载

优化方式

按需加载

路由按需加载

const OtherRouter = [
  {
    path: "/test",
    name: "Test",
    component: () => import(/* webpackChunkName: "test" */ "@/views/Test.vue")
  },
  {
    path: "/config",
    name: "config",
    component: () => import("@/views/other/config.vue")
  }
];

第三方组件和插件,按需引入第三方组件

import Vue from 'vue';
import { Button, Select } from 'element-ui';
import App from './App.vue';

Vue.component(Button.name, Button);
Vue.component(Select.name, Select);

对于一些插件,如果只是个别组件中使用到就不要在main.js或者main.ts中引入了

- import Vditor from 'vditor'
- Vue.use(Vditor)
//组件内
+ import Vditor from 'vditor'

优化loader配置

  • 优化正则匹配
  • 通过 cacheDirectory 选项开启缓存
  • 通过 include、exclude 来减少被处理的文件

优化文件路径

  • extension 配置之后可以不用在 require 或是 import 的时候加文件扩展名,会依次尝试添加扩展名进行匹配。
  • mainFiles 配置后不用加入文件名,会依次尝试添加的文件名进行匹配
  • alias 通过配置别名可以加快 webpack 查找模块的速度

vue

  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },

angular

tsconfig.json

 "paths": {
      "@service/*": ["app/service/*"],
      "@pipes/*": ["app/pipes/*"]
    },

生产环境关闭 sourceMap

  • sourceMap 本质上是一种映射关系,打包出来的 js 文件中的代码可以映射到代码文件的具体位置,这种映射关系会帮助我们直接找到在源代码中的错误
  • 打包速度减慢,生产文件变大,所以开发环境使用 sourceMap,生产环境则关闭

代码压缩

  • UglifyJS: vue-cli 默认使用的压缩代码方式,它使用的是单线程压缩代码,打包时间较慢
  • ParallelUglifyPlugin: 开启多个子进程,把对多个文件压缩的工作分别给多个子进程去完成
npm i -D webpack-parallel-uglify-plugin

webpack.prod.js文件配置如下

const path = require('path')
const webpackConfig = require('./webpack.config.js')
const WebpackMerge = require('webpack-merge')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
// const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const ParallelUglifyPlugin = require("webpack-parallel-uglify-plugin");

module.exports = WebpackMerge(webpackConfig, {
    mode: 'production',
    devtool: 'cheap-module-source-map',
    plugins: [
 new CopyWebpackPlugin([{
            from: path.resolve(__dirname, '../public'),
            to: path.resolve(__dirname, '../dist')
    }]),
  ],
    optimization: {
        minimizer: [
 // new UglifyJsPlugin({//压缩js
 //   cache:true,
 //   parallel:true,
 //   sourceMap:true
 // }),
 new ParallelUglifyPlugin({
                cacheDir: '.cache/',
                uglifyJS: {
                    output: {
                        comments: false,
                        beautify: false,
                    },
                    compress: {
                        drop_console: true,
                        collapse_vars: true,
                        reduce_vars: true
                    }
                }
            }),
 new OptimizeCssAssetsPlugin({})
    ],
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                libs: {
                    name: "chunk-libs",
                    test: /[\\/]node_modules[\\/]/,
                    priority: 10,
                    chunks: "initial" // 只打包初始时依赖的第三方
                }
            }
        }
    }
})

引入webpack-bundle-analyzer分析打包后的文件

webpack-bundle-analyzer将打包后的内容束展示为方便交互的直观树状图,让我们知道我们所构建包中真正引入的内容

npm i -D webpack-bundle-analyzer

webpack.prod.js中加入代码

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
 
 plugins:[
  ...,
  new BundleAnalyzerPlugin({
      analyzerHost:'127.0.0.1',
      analyzerPort: 8889
    })
  ],

在package.json中加入配置

"analyz": "NODE_ENV=production npm_config_report=true npm run build"

windows请安装

npm i -D cross-env
"analyz": "cross-env NODE_ENV=production npm_config_report=true npm run build" 

CDN加速

随着应用越做越大,第三方包越来越多,构建的文件肯定随之越来越大,加上又是单页应用,就会导致网速过慢或者贷款有限的情况会由于较长时间的白屏

vue,vue-router,vuex,axios....

目前常用的cdn加速网站 UNPKG

使用HappyPack多进程解析

  • 由于运行在 Node.js 之上的 Webpack 是单线程模型的,所以 Webpack 需要处理的事情需要一件一件的做,不能多件事一起做。
  • HappyPack 就能让 Webpack 把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程
  • HappyPack 对 file-loader、url-loader 支持的不友好,所以不建议对该 loader 使用

使用方法

1、HappyPack 插件安装: npm i -D happypack
2、webpack.base.conf.js 文件对 module.rules 进行配置

module: {
  rules: [
    {
      test: /\.js$/,
      use: ['happypack/loader?id=babel'],
      include: [resolve('src'), resolve('test')],
      exclude: path.resolve(__dirname, 'node_modules')
    },
    {
      test: /\.vue$/,
      use: ['happypack/loader?id=vue']
    }
  ]
}

3、在生产环境 webpack.prod.conf.js 文件进行配置

const HappyPack = require('happypack')
// 构造出共享进程池,在进程池中包含5个子进程
const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })
plugins: [
  new HappyPack({
    // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
    id: 'babel',
    // 如何处理.js文件,用法和Loader配置中一样
    loaders: ['babel-loader?cacheDirectory'],
    threadPool: HappyPackThreadPool
  }),
  new HappyPack({
    id: 'vue', // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
    loaders: [
      {
        loader: 'vue-loader',
        options: vueLoaderConfig
      }
    ],
    threadPool: HappyPackThreadPool
  })
]

TreeShaking

这里单独提一下tree-shaking,是因为这里有个坑。tree-shaking的主要作用是用来清除代码中无用的部分。目前在webpack4我们设置modeproduction的时候已经自动开启了tree-shaking。但是要想使其生效,生成的代码必须是ES6模块。不能使用其它类型的模块如CommonJS之流。如果使用Babel的话,这里有一个小问题,因为Babel的预案(preset)默认会将任何模块类型都转译成CommonJS类型。修正这个问题也很简单,在.babelrc文件或在webpack.config.js文件中设置modules: false就好了

0

评论区