Webpack——基础优化方法

933 阅读2分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

打包速度

bable-loader

在babel.config.js中配置

options: {
 // 开启缓存,避免重复打包
 cacheDirectory: true
}]
// 设置include或exclude,打包或排除某个文件夹
include: path.json(__dirname, '..', 'src')
exclude: path.resolve(__dirname, 'node-modules')

exclude让项目打包时间从17.43s降到12.51s

noParse

不打包指定文件,但打包后会包含此文件(用户不发生变化的文件)

configureWebpack: {
  module: {
    noParse: [/vue.min.js$/],
  },
},

happyPack多进程打包

重点:多进程也会增加额外消耗,所以项目小的时候有可能回增加打包时间,推荐项目较大时使用。

const happyPack = require('happypack');
chainWebpack: config => {
  config.module
    .rule('js')
    .test(/.js$/)
    .use('happypack/loader?id=babel')
    .loader('babel-loader')
    .options({ exclude: path.resolve(__dirname, 'node-modules') });
} 
plugins: [
  new happyPack({
    id: 'babel',
    loaders: ['babel-loader?catchDirectory'],
  }),
], 

ParallelUglifyPlugin多进程压缩

正常打包是通过UglifyJS进行压缩,但UglifyJS没办法多进程并行打包,因此ParallelUglifyPlugin诞生了,主要是配合happyPack进行多进程打包,每个子进程还是通过UglifyJS打包

DllPlugin

提前把不经常改动的文件进行打包,之后上线打包不再重复打包。

新建webpack.dll.conf.js

const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    vender: ['vue/dist/vue.esm.js', 'vue-router', 'axios', 'vuex'],
  },
  output: {
    path: path.join(__dirname, '../public/static'),
    filename: '[name].dll.js',
    library: '[name]_library',
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, '.', '[name]-manifest.json'),
      name: '[name]_library',
    }),
  ],
};

新增命令

"dll": "webpack --config build/webpack.dll.conf.js"

vue.config.js

chainWebpack: config => {
  if (process.env.NODE_ENV === 'production') {
    // dll优化
    config.plugins.push(
      new webpack.DllReferencePlugin({
        context: process.cwd(), //当前目录
        manifest: require('./build/vender-manifest.json'),
      }),
    );
    // 将打包出来文件动态引入index.html
    // 或者手动添加<script src="./static/vender.dll.js"></script>
    config.plugins.push(
      new AddAssetHtmlPlugin({
        // dll文件位置
        filepath: path.resolve(__dirname, './public/static/vender.dll.js'),
        // dll 引用路径
        publicPath: './static/',
        outputPath: './static/', // 输出的目录地址
      }),
    );
  }
},

打包体积

Webpack.IgnorePlugin:忽略第三方包指定目录,让这些指定目录不要被打包进去

使用前:

使用后:

// 配置
configureWebpack: {
  plugins: [new Webpack.IgnorePlugin(/./locale/, /moment/)],
},

import moment from 'moment';
moment.locale('zh-cn');
console.log(moment.locale());
console.log(moment.format()); 

图片的处理

较小的图片打包成base64,减少网络请求,较大的图片不变,保证js不会太大(base64长度和图片大小有关)。使用url-loader配置就可以。

开发体验

HotModuleReplacementPlugin

webpack-dev-server的热更新是重新刷新页面这样更新慢、需要重新请求资源,开发体验很差。HotModuleReplacementPlugin能过做的保留状态的热更新,开发体验极佳。

热更新原理:

通过下面函数添加监听,被监听的文件发生变化时会触发绑定的函数。vue中就是监听了所有文件。有些css用的的loader中内置了监听。

if(module.hot) {
  module.hot.accept(['./main.js'], () => {
    console.log('hello');
  })
}