webpack高级配置(1)

60 阅读3分钟

什么是高级配置

即对webpack配置优化,让代码在编译/运行时性能更好。 常用的优化角度

  • 1.提升开发体验
  • 2.提升打包速度
  • 3.减少代码体积
  • 4.优化代码性能

几种常用高级配置

sourceMap

soureMap源代码映射,是一个用来生成源代码与构建勾代码--映射文件的方案。 一旦构建后代码错误,或找到映射的源代码位置,从而让浏览器其实源代码错误位置 source-map的类型有多种对比起个类型:

image.png

更多类型及详情见官方文件www.webpackjs.com/configurati…

soureMap-quality()注解
  • 打包后的代码 - 将所有生成的代码视为一大块代码。你看不到相互分离的模块。
  • 生成后的代码 - 每个模块相互分离,并用模块名称进行注释。可以看到 webpack 生成的代码。
  • 转换过的代码 - 每个模块相互分离,并用模块名称进行注释。可以看到 webpack 转换前、loader 转译后的代码。
  • 源代码 - 每个模块相互分离,并用模块名称进行注释。你会看到转译之前的代码,正如编写它时。这取决于 loader 支持。
  • (仅限行) - source map 被简化为每行一个映射。这通常意味着每个语句只有一个映射(假设你使用这种方式)。这会妨碍你在语句级别上调试执行,也会妨碍你在每行的一些列上设置断点。与压缩后的代码组合后,映射关系是不可能实现的,因为压缩工具通常只会输出一行

实际在开发中只关心两种情况

  • 1.source-map 生产模式 错误信息包含行/列,但缺点是打包速度更慢
module.exports = {
    mode: 'producetion',
    devtool: 'source-map',
}
  • 2.cheap-module-source-map 开发模式代码未被压缩 错误定位到行已满足需求
module.exports = {
    mode: 'development',
    devtool: 'cheap-module-source-map',
}
hotModuleReplacement 热模块替换
为什么要使用hotModuleReplacement?

根据webpack的执行流程执行一次打包默认执行打包全部文件,hotModuleReplacement用来只替换、添加或删除模块

使用

1.webpack自带热替换模块

const webpack = require('webpack')

2.devServe引入

devServer: {
        host: '0.0.0.0',
        port: 8080, // 端口号
        https: false, // https:{type:Boolean}
        open: true, //配置自动启动浏览器
        hot: true, //开启hMr
  
    },

3.plugin配置

plugins:[
new CleanWebpackPlugin()
new webpack.HotModuleReplacementPlugin()

]

4.对js处理 来通知 webpack 的 HMR 我们接收了这个模块,HMR 并不需要再重新执行模块的替换

if (module.hot) {
    module.hot.accept('./utils/sum.js')
}

vue项目使用vue-loader 进行热替换

oneOf
什么是oneOf

oneOf 对loader的执行效率提升 只要匹配到一种解析loader执行后其他loader跳过,来提高构建速度。 用法

  module: {
    rules: [
    //当有两个配置处理同一文件,就提到oneOf外面来
        {
            test: /\.js$/,
            exclude: /node_modules/,
            enforce: 'pre',//优先处理
            loader: 'eslint-loader',
        },
        {
            // 以下loader只能匹配一个文件
            // 注意:不能有两个配置处理同一个文件
            oneOf: [
                {
                    test: /\.css$/,
                    use: [
                      "style-loader",
                      "css-loader"
                    ]
                },
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    loader: 'babel-loader',
                },
            ]
        },
    ]
},


exclude

打包资源时exclude过滤掉不需要重新打包的资源比如:node_module

 module: {
   rules: [
         {
         test: /\.js$/, // 1.匹配 .css 结尾的文件,注意test的值不是一个字符串,而是一个正则
         exclude: /(node_modules|bower_components)/, // 2.排除这两个文件不需要打包
         include:path.resolve(_dirname,'../src') ,
        }
         ]
        }

exclude和include只生效一个配置

cache

每次打包时js文件都需要eslint检查和babel编译,速度比较慢,我们可以用cache缓存之前的eslint检查和babel编译结果,这样之后的打包速度会更快

使用 1.对eslint配置 安装

npm install eslint-webpack-plugin --save-dev

配置

 const ESLintPlugin=require('eslint-webpack-plugin')
 plugins:[
   new ESLintPlugin({
     context:path.resolve(___dirname,'../src'),
     exclude:'node_modules',
     cache:true,
     cacheLoaction:path.resolve(___dirname,'../node_modules/.cache/eslintCache') //cache存放的位置
   })
 ]

2.对babel-loader配置


module.exports = {
    // ...
    module: {
        rules: [{
            test: /.m?js$/,
            loader: 'babel-loader',
            options: {
                cacheDirectory: true,
            },
        }]
    },
    // ...
};
cacheDirectory 文件默认目录位置为node_modules/.cache/babel-loader
thead多进程打包

当项目越来越庞大的时候打包速度变慢,主要是因为js打包速度慢

开启电脑的多进程同时做一件事,速度更快。

怎么用 1.获取设备cpu核数,因为每台电脑不一样

const os=require('os') const threads=os.cpu().length

2.下载包 npm i thread-loader -D

3.配置 loader配置

const os=require('os')
const threads=os.cpu().length
{
  // 当js代码用babel处理兼容性且本身代码就比较多的情况下可以使用thread-loader开启多线程打包
  // thread-loader本身启动进程就需要耗费时间, 所以当js代码不多时就不要开启, 否则还可能会延长打包时间
  test: '/\.js$/',
  exclude: /node_modules/,
  use: [
    {
      loader: 'thread-loader',
      options: {
        // 默认是cpu核 - 1, 可以通过这里更改开启几个进程
        works: threads
      }
    },
  ........
  ]

}

eslint插件配置

new ESLintPlugin({
    // exclude: path.resolve(__dirname, '../src/components/'),
    context: path.resolve(__dirname, '../src'),
    // 开启缓存
    cache: true,
    // 指定缓存目录
    cacheLocation: path.resolve(__dirname, '../node_modules/.cache/eslintCache'),
    // 开启多进程和进程数量
    threads:threads
}),

terser

webpack5以上自带terser插件 配置


const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
    optimization: {
        minimize: true,
        minimizer: [new TerserPlugin({
            test: /.js(?.*)?$/i,    //匹配参与压缩的文件
            parallel: true,    //使用多进程并发运行
            terserOptions: {    //Terser 压缩配置
                output:{comments: false}
            },
            extractComments: true,    //将注释剥离到单独的文件中
                compress: {//console删除
                    pure_funcs: ["console.log"]
                }
        })],
    },
};

Tree Shaking

tree Shaking 用于移除js中未使用的代码

开发时我们定义以一些工具函数库或者引用第三方工具函数或者组件库,如果没有特殊处理的话我们打包时会引入整个库,但实际上也许我们只用到小部分功能,这样体积过大。

webpack5已经默认开启这个功能,无需其他配置

babel-plugin-transform-runtime

babel编译的时候为每个文件加入辅助代码例如 _extend。这样文件多的时候,项目就会很大。

所以 babel 提供了 transform-runtime 来禁用了babel自动对每个文件的runtime注入并且将这些辅助函数“搬”到一个单独的模块 babel-runtime 中,这样做能减小项目文件的大小。

安装

 npm i  @babel/plugin-transform-runtime  -D

配置

```js
 {
   loader:'babel-loader',
   options:{
     cacheDirectory:true,  //开启babel编译缓存
     cacheCompression:false //缓存文件不压缩
     plugins:['@babel/plugin-transform-runtime']
   }
 }
image minimizer

本地静态图片压缩插件

使用:

安装

npm i image-minimizer-webpack-plugin imagemin -D

还需要安装

二选一
// 无损压缩
 npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
// 有损压缩
 npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo -D

配置

图片压缩ImageMinimizerPlugin

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png)$/i,
        type: "asset",
      },
    ],
  },
 optimization: {
    minimizer: [
         // 压缩图片
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminGenerate,
          options: {
            plugins: [
              ["gifsicle", { interlaced: true }],
              ["jpegtran", { progressive: true }],
              ["optipng", { optimizationLevel: 5 }],
              [
                "svgo",
                {
                  plugins: [
                    "preset-default",
                    "prefixIds",
                    {
                      name: "sortAttrs",
                      params: {
                        xmlnsOrder: "alphabetical",
                      },
                    },
                  ],
                },
              ],
            ],
          },
        },
      }),
        ]
    }
};