Webpack2.x->webpack5.x升级记录

1,047 阅读2分钟

Webpack2.x->webpack5.x升级记录

由于项目工程编译速度和开发效率过慢,我决定升级项目的webpack到最新的5.X

Upgrade webpack version

yarn add webapck webapck-cli -D

当下安装好后

webpack: "^5.70.0"
webpack-cli: "^4.9.2"

Compile your project to find some error and to fix it

yarn start or yarn dev according your project

  1. extract-text-webpack-pluginmini-css-extract-plugin代替

  2. webpack-dev-server 升级,使用改为webpack serve --config webpack.config.js

  3. url-loaderfile-loader 被 webpack内置的asset/source代替

  4. htmlWebpackPlugin.files.chunkshtmlWebpackPlugin.files.js 代替

  5. webpack.optimize.UglifyJsPluginuglifyjs-webpack-plugin 代替

  6. CommonsChunkPluginoptimization.splitChunks代替

  7. 下面的配置中列出部分配置

    const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
    ​
    target: process.env.NODE_ENV === 'production' ? 'browserslist' : 'web', // 配合热更新,dev下设置为web才可以正常使用热更新的功能
    mode: mode, // webpack5对mode非常严格
    output: {
      clean: true, // 代替clean-webpack-plugin, 每次打包时会先清除打包目录里的文件
      assetModuleFilename: 'static/[name]_[hash:6][ext][query]' // 定义全局的asset输出路径
    },
    rule:[{
      test: /\.(png|jpg|jpeg|gif)$/i,
      type: 'asset',
      parser: {
        dataUrlCondition: {
          maxSize: 2 * 1024 // 如果小于制定的size,则转换为base64,使用asset/inline type,如果大于size, 则使用asset/resource,类似于file-loader
        }
      },
      generator: {
        filename: 'images/[name][ext][query]'
      }
    }],
    plugins: [
      new DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(mode), // 必须和mode一样,不然会报NODE_ENV冲突
        'process.env.BABEL_ENV': JSON.stringify(process.env.NODE_ENV) // 单独对BABEL_ENV设置,它可以自定义,可以不是production/development
      })
    ]
    
  8. devServer 配置

    devServer: {
      hot: true, //配置热更新
      liveReload: false, // 禁用reload page功能,我们使用热更新,局部刷新,不要浏览器的刷新功能
      devMiddleware: {
        writeToDisk: true // 配合copyWebpackPlugin,因为热更新之后,copy出去的文件在刷新浏览器的时候会丢失,必须设置
      }
    }
    
  9. React-hot-loader

    // .babelr
    {
      "env": {
        "static" :{ // 对应DefinePlugin中的process.env.BABEL_ENV,环境变量
          "plugins": [
            "react-hot-loader/babel"
          ]
        }
      }
    }
    ​
    // entry
    entry: {
      'index.js': ['react-hot-loader/patch', 'src/index.jsx'] // patch必须在我们的入口文件之前
    }
    ​
    // plugin
    plugins: [
      new webpack.HotModuleReplacementPlugin();
    ]
    ​
    // 文件主入口 index.jsx
    if(module.hot){
      module.hot.accept(); // 接受我们的热更新
    }
    ​
    // optimization 相关
    optimization: {
      runtimeChunks: 'single',
      chunkIds: 'named',
      moduleIds:'named'
    }
    
  10. htmlwebpackPlugin

    plugins: [
      new HtmlWebpackPlugin({
        filename: 'index.html',
        inject: true, // 向输出文件中注入chunks,也可以设置为false,然后模版中自定义使用htmlWebpackPlugin.files.js来拿到所有的chunk文件
        template: 'src/index/index.html', // 参考模版
        favicon: 'public/favicon.ico'
      })
    ]
    
  11. 优化配置

    // development配置
    optimization: {
      runtimeChunks: 'single',
      chunkIds: 'named',
      moduleIds:'named',
      // treeshaking【树摇】, 将定义但是没有引用的export在打包的时候删除, 同时需要在package.json中提供sideEffects属性,    false or ['*.css', '*.less']
      usedExports: true,
      // 提取公共代码出来
      splitChunks: {
        chunks: 'all',
          cacheGroups: {
          defaultVendors: {
            filename: 'vendors.[contenthash:8].js'
          }
        }
      },
      minimizer: [
        new UglifyJsPlugin({
          cache: true,
          sourceMap: false,
          uglifyOptions: {
            warnings: false,
            compress: {
              unused: true,
              dead_code: true,
              drop_console:true,
              drop_debugger: true
            }
          }
        })
      ]
    }
    

如果你的过程出现eslint报错: no-undef

可以安装最新的eslint-scope yarn add eslint-scope -D