webpack 常用配置解析(二)

1、配置eslint语法检查

/**
       * 语法检查 eslint-loader eslint
       * 设置检查规则: 
       *    package.json 中 eslintConfig中设置 或者创建.eslintrc.js文件
       *    // https://www.npmjs.com/package/eslint-config-airbnb-base
       *    airbnb-->eslint-config-airbnb-base eslint eslint-plugin-import eslint-import-resolver-node
       * 
       */
      {
        test: /\.js$/,
        exclude: /node_modules/, // 注意只检查自己写的源代码,第三方库不用检查
        loader: 'eslint-loader',
        options:{
          "fix": true // 自动修复eslint错误
        }
      },

.eslintrc.js https://www.jianshu.com/p/c81757b9b086

module.exports = {
  "env": {
    "browser": true,
    "es2021": true,
    "node": true
  },
  "extends": "airbnb-base"
}

2、js的兼容性处理

{
        /**
         * js兼容处理  babel-loader @babel/core 
         * 1、基本js兼容吃处理 --》 @babel/preset-env
         * 2、全部js兼容处理 -->    @babel/polyfill (在js文件从 import "@babel/polyfill" 即可,不过会把很多没用到的兼容打包)
         * 3、解决部分项目中用到的兼容性问题 按需加载。---》corejs  如果运行报错的话,js文件引入 import "core-js/stable";  import "regenerator-runtime/runtime";
         * 
        */
       test: /\.js$/,
       exclude: /node_modules/,
       loader: 'babel-loader',
       options: {
         // 预设: 指示babel做怎么样的兼容性处理
         presets: [
           [
            '@babel/preset-env',
            {
              useBuiltIns: 'usage', // 按需加载
              corejs: {
                version: 3, //指定版本
                proposals: true
              },
              // 指定兼容到哪个版本
              targets:{
                chrome: '60',
                firefox: '60',
                ie: '9',
                safari: '10',
                edge: '17'
              }
            }
           ]
         ]
       }
      },

image.png

https://babeljs.io/blog/2019/03/19/7.4.0#migration-from-core-js-2

3、js压缩

 mode: "production" // 会自动压缩 会自动调用 UglifyJsPlugin插件

4、html压缩

new HtmlWebpackPlugin({
      // 模板
      template: './index.html',
      minify:{
        //移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    }),

5、性能优化

开发环境

  • 优化打包构建速度
  • 优化代码调试

生产环境

  • 优化打包构建速度
  • 优化代码运行性能

优化打包构建速度
1开启热更新
特别注意webpack 5中需要设置target:'web'才能开启热更新

image.png

target: 'web',
devServer: {
      hot: true,
}

HMR hot mdule replacement 热模块替换

作用一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度

  • 样式文件:可以使用 HMR功能,style-loader内部实现了。(所以开发模式下一般不要使用css文件提取,使用style-loader)
  • js文件:默认不能使用HMR功能,----》需要修改js代码,添加支持HMR功能的代码。 注意:HMR功能对js的处理,只能处理非入口js文件的其他文件
index.js
import './test.js'
if(module.hot){
  console.log('hot');
  // 一旦 module.hot为true,说明开启了HMR功能
  module.hot.accept('./test.js', ()=>{
    // 方法会监听test.js文件变化
    console.log('test.js变化了');
  })
}

  • html文件,默认不能使用HMR功能(如果要使用,在entry中引入html文件),同时会导致问题:html文件不能热更新(因为html文件变化,就会重新引入其他文件,所以不用做HMR功能。)

6、sourceMap(devtool)

/**
 * source-map: 一种提供源代码到构建后代码映射技术 https://webpack.docschina.org/configuration/devtool/#root
 * [inline-|hidden|eval-][nosources-][cheap-[moudle-]]source-map
 * source-map 外部 错误代码和源代码位置
 * inline-source-map 内联 错误代码和源代码位置 只生成一个内联 source-map
 * hidden-source-map 外部 错误代码只提供构建后错误位置  只隐藏源代码,会提示构建后的错误
 * eval-source-map 内联   错误代码和源代码位置  生成多个内联 source-map
 * nosources-source-map 外部 错误代码无源代码信息  全部隐藏
 * cheap-source-map 外部  错误代码和源代码位置(只提示到行)
 * cheap-module-source-map 外部 错误代码和源代码位置(只提示到行) module会将loader中source map加入
 * 
 * 
 * 
 * 开发环境: 速度快,调试友好
 *    速度(eval>inline>cheap...)
 *    eval-cheap-source-map
 *    eval-source-map
 *    调试友好
 *    source-map
 *    cheap-module-source-map
 *    cheap-source-map
 * 
 * 综合取: eval-source-map | eval-cheap-module-source-map
 * 
 * 生产环境: 源代码是否要隐藏, 调试要不要友好
 *    内联会让代码体积变大,所有生产用外部
 *    如果要隐藏
 *    hidden-source-map 
 *    nosources-source-map
 *  
 * 不隐藏的话  
 * 综合取: source-map | cheap-module-source-map
 * */
  devtool: 'eval-cheap-source-map'

7、oneof (每一个文件都会到loader中过一遍)

 module: {
    rules: [
      {
        // loader只会匹配一个
        // 由于只能匹配一个,所有如果下面有匹配两个js 一个做eslitn 一个做兼容处理, 需要提取一个到外面
        oneOf: [
          {
            test: /\.css$/,
...

8、生成环境缓存
对babel进行缓存cacheDirectory: true (让第二次构建速度更快)

test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
              // 开启babel缓存
              // 第二次构建时,会读取之前的缓存
              cacheDirectory: true,
...

但是如果有修改之后,上线,页面引入的js,css名称没有变化,这时会读取浏览器缓存,造成修改失败。这个时候就需要给js和css添加hash值,这样打包修改后。引入的js,css就会发生变化

// 输出
  output: {
    filename: 'js/[name].[hash:10].js', // 给js增加hash
    path: path.resolve(__dirname, 'build')
  },
...
plugins: [ 
 new MiniCssExtractPlugin({
      filename: 'css/[name].[hash:10].css'
    }),

hash 区别 (让代码上线运行缓存更好用)
上面 如果我们改js,css也会重新打包。
为了解决看看以下区别

  • hash: 每一次webpack构建时会生成唯一的一个hash值
  • chunkhash: 根据chunk生成的hash值,如果打包来源于同一个chunk,那么hash值一样(一个入口文件, 入口文件里面移入其他文件,这些些都属于同一个chunk)
  • contenthash: 根据文件的内容生成的hash值,不同文件的hash值不一样

所有 上面的hash缓存改为contenthash就可以了。

9、tree-shaking (去掉没有使用的代码)

/**
 * tree shaking
 * 1.使用es6模块  2.mode为production
 * 作用: 减少代码体积
 *  package.json中设置
 *  "sideEffects": false 所有代码都没有副作用 (都可以进行tree shaking)
 *   问题: 会把其他引入的 css文件给清除掉
 *   所有需要设置 sideEffects: ["*.css", "*.less"]
 * 
 * */ 

10、单独打包node_modules

//入口
  entry: {
    index: './src/index.js', index2: './src/index2.js'
  },
  // 输出
  output: {
    filename: 'js/[name].[contenthash:5].js',
    path: path.resolve(__dirname, 'build')
  },
  /**
   * 将 node_modules中代码单独打包成一个chunk最终输出
   * 并且分析多入口chunk中,有没有公共的文件,如果有会打包成单独的一个chunk
  */
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  },

11、把单独js打包

/***
 * 通过js代码,单独打包某个文件为一个chunk 
 * import 动态导入语法: 将某个文件单独打包
 * / * webpackChunkName:'命名打包后的文件名' * /
 * */ 
import(/* webpackChunkName:'hahaha' */'./dandu.js').then(()=>{
  console.log('文件加载成功');
}).catch(()=>{
  console.log('文件加载失败');
})

webpack 常用配置解析(一)
webpack 常用配置解析(二)
webpack 常用配置解析(三)

你可能感兴趣的:(webpack 常用配置解析(二))