Skip to content

迁移注意

  1. webpack 5 要求至少 Node.js 10.13.0 (LTS)
  2. To v5 from v4

升级步骤

1. webpack webpack-cli等升级

yarn add webpack@latest -D
yarn add webpack-cli@latest -D
yarn add html-webpack-plugin@latest -D
// yarn add vue-loader@latest @vue/compiler-sfc -D // vue-loader相关两个不建议升级到最新, vue-loader到15.9.6就OK了, compiler-sfc 针对Vue3的

2.其他依赖升级

  1. yarn add babel-loader@latest -D
  2. 删除项目中无用的ESlint,重新配置
"eslint": "^5.9.0",
"eslint-config-standard": "^12.0.0",
"eslint-loader": "^2.1.1",
"eslint-plugin-html": "^4.0.6",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-node": "^8.0.0",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.3",
"firebase": "4.6.2", // 无用
"babel-plugin-transform-runtime": "^6.23.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0", // ??
"babel-preset-env": "^1.6.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-dynamic-import-node": "^2.3.0",
"babel-core": "^6.26.3", // 8配置改变
"@babel/eslint-parser": "^7.13.14", // 删掉
"btoa": "^1.2.1",
"atob": "^2.1.1",

优化分析

打包速度优化分析

bash
yarn add speed-measure-webpack-plugin -D

打包体积优化分析

bash
# NPM
npm install --save-dev webpack-bundle-analyzer
# Yarn
yarn add -D webpack-bundle-analyzer

Usage (as a plugin)

js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

错误处理

1. Tapable.plugin is deprecated

bash
(node:29283) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead

解决:

  1. Use node --trace-deprecation ... to show where the warning was created
  2. webpack.base.config.js中设置process.traceDeprecation = true
js
process.traceDeprecation = true

webpackConfig = merge(webpackBaseConfig, {
    //....
})
module.exports = webpackConfig
// npm run xxx

追踪到warning在speed-measure-webpack-pluginwebpack-uglify-parallel中使用了废弃的api

bash
(node:29694) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
    at Proxy.<anonymous> (/xxxx/speed-measure-webpack-plugin/WrappedPlugin/index.js:69:17)
    at UglifyJsParallelPlugin.apply (/xxxxx/webpack-uglify-parallel/index.js:33:11)
  • 删除webpack-uglify-parallel,改用webpack-parallel-uglify-plugin

2. uglifyjs-webpack-plugin

使用terser-webpack-plugin,删除uglifyjs-webpack-plugin相关配置

3. source-map

// webpack4
devtool: cheap-eval-module-source-map

// webpack5
devtool: eval-cheap-module-source-map // 写法更改了

4. webpack-merge

yarn add webpack-merge@latest -D

// webpack 4.X
const merge = require('webpack-merge')

// webpack 5.x
const { merge } = require('webpack-merge')

5. copy-webpack-plugin

js
// webpack 4.X
new CopyPlugin([
    {
        from: path.resolve(__dirname, '../public'),
        to: config.build.assetsRoot,
        ignore: ['\.*']
    },
]),

// webpack 5.X
new CopyPlugin({
    patterns:[
        {
            from: path.resolve(__dirname, '../public'),
            to: config.build.assetsRoot,
            globOptions:{
                ignore: ['\.*']
            }
        },
        
    ]
}),

6. optimize-css-assets-webpack-plugin

官方准备弃用了,改用css-minimizer-webpack-plugin

bash
yarn add -D css-minimizer-webpack-plugin
js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')

minimizer: [
    // new OptimizeCSSAssetsPlugin({
    //     cssProcessorOptions: {
    //         safe: true
    //     }
    // })
    new CssMinimizerPlugin({
        parallel: true,
    })
]

7. babel-loader

bash
Error: Compiling RuleSet failed: Query arguments on 'loader' has been removed in favor of the 'options' property (at clonedRuleSet-1[0].rules[0].loader: babel-loader?cacheDirectory)
js
// loader: 'babel-loader?cacheDirectory',

// 改为
loader: 'babel-loader'

8.speed-measure-webpack-plugin

不兼容webpack5,报错

DeprecationWarning: Compilation.hooks.normalModuleLoader was moved to NormalModule.getCompilationHooks(compilation).loader

9.vue-loader

vue-loader

js
// Error: Cannot find module 'vue-loader/lib/plugin'
const VueLoaderPlugin = require('vue-loader/lib/plugin') 
// 或者
const { VueLoaderPlugin }  = require('vue-loader') 

plugins:[
    new VueLoaderPlugin(),
]

加上smp.wrap后报错

bash
Module Error (from ./node_modules/vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
 @ ./src/app.js 8:0-28 87:15-18
 @ ./src/entry-client.js 3:0-34 42:17-26

10.new webpack.HashedModuleIdsPlugin(),

TypeError: webpack.HashedModuleIdsPlugin is not a constructor

暂时注释掉

11. babel-loader升级到8

yarn add -D babel-loader @babel/core @babel/preset-env  // 必须装
// 搞定浏览器不兼容的Api Promise,Set,Symbol等什么的
yarn add @babel/runtime @babel/plugin-transform-runtime -D  // 必须装
yarn add @babel/plugin-proposal-object-rest-spread --d  // 
// https://www.babeljs.cn/docs/babel-plugin-proposal-object-rest-spread

12. polyfill

webpack5中移除了node核心模块polyfill的自动引入, 需要手动引入, 如果打包过程中使用到了, 需要进行相应配置, 并安装相应依赖

js
module.exports = {
    resolve:{
        fallback:{
            url: require.resolve('url'),
            timers:require.resolve("timers-browserify"),
        }
    }
}
js
plugins: [
    // fix "process is not defined" error:
    // (do "npm install process" before running the build)
    new webpack.ProvidePlugin({
        process: 'process/browser',
    }),
]

13. less-loader

bash
ValidationError: Invalid options object. Less Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'javascriptEnabled'. These properties are valid:
   object { lessOptions?, additionalData?, sourceMap?, webpackImporter?, implementation? }

less-loader 6.X以上,配置要修改

js
// old
{
    loader: "less-loader",
    options: {
        javascriptEnabled: true
    }
}
// new
// https://github.com/ant-design/ant-design-landing/issues/235
{
    loader: "less-loader",
    options: {
        lessOptions:{
        javascriptEnabled: true
        }
    }
}

14. ReferenceError: Buffer is not defined

排查发现引入的btoa,atob模块中,Buffer在浏览器和node环境中兼容不一致造成 改写Base64 decode和encode方法

js
const atobImp = (b64Encode) => {
    try {
        return atob(b64Encode) // 浏览器window对象自带
    }catch(err){
        return Buffer.from(b64Encoded, 'base64').toString()
    }
}

const btoaImp = (str) => {
    try {
        return btoa(str) 
    }catch(err){
        return Buffer.from(str).toString('base64')
    }
}

15. img标签中src为[object Module]

url-loader中配置esModule:false

js
{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 5000,
        name: utils.assetsPath('img/[name].[hash:7].[ext]'),
        esModule:false // 关闭url-loader中ES6模块化,使用commonjs解析
    }
},

16. mini-css-extract-plugin警告

这个警告可以忽略,因为组件加载顺序不同,对css没影响

bash
WARNING in chunk 563 [mini-css-extract-plugin]
Conflicting order. Following module has been added:
 * css ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-6[0].rules[0].use[1]!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/thread-loader/dist/cjs.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/views/app/components/CareAppVipTip.vue?vue&type=style&index=0&id=043396ff&lang=scss&scoped=true&
despite it was not able to fulfill desired ordering with these modules:
 * css ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-6[0].rules[0].use[1]!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js!./node_modules/sass-loader/dist/cjs.js!./node_modules/thread-loader/dist/cjs.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/views/search/components/SearchNav.vue?vue&type=style&index=0&id=8031f10e&lang=scss&scoped=true&
   - couldn't fulfill desired order of chunk group(s) group-search
   - while fulfilling desired order of chunk group(s) group-asmMonitor
js
new MiniCssExtractPlugin({
  ignoreOrder: true,
}),

17. vue-server-renderer

(node:18852) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.
BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
        Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
        Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.
    at /Users/zxd/Documents/qimai-workspace/appdata_web/node_modules/vue-server-renderer/client-plugin.js:86:49

Clean up configuration

  1. [hash][contenthash] 在 webpack 配置中使用[ hash ]占位符时,考虑将其更改为[ contenthash ], 内容级别的修改改变hash值.

PNG,字体,MP4等静态资源

{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 5000,
        name: utils.assetsPath('img/[name].[contenthash:7].[ext]'),
        esModule:false
    }
}

PS.

-S -D

  • --save 简写-S, 是默认命令,当使用npm install [fileName]命令时默认调用,会把下载文件的信息记录至package.json的dependencies属性中
  • --save-dev 简写-D, 会把信息记录至devDependencies属性中

版本号

  • 主版本号.次版本号.补丁版本号
  • ~2.1.x 会安装2.1.x最新版本,可以是 2.1.2, 2.1.5, 2.1.9,不会到 2.2.x;
  • ^2.1.x 会安装2.1.x以上版本,2.5.0, 2.9.9,不会到3.0.0
  • ~1.2.3 >= 1.2.3 < 1.3.0
  • ^1.2.3 >=1.2.3 < 2.0.0

查看CPU,OS信息

// run:
npx envinfo --system --binaries --npmPackages clean-webpack-plugin,webpack
bash
  System:
    OS: macOS 10.15.7
    CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
    Memory: 19.04 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.20.1 - ~/.nvm/versions/node/v12.20.1/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v12.20.1/bin/yarn
    npm: 6.14.10 - ~/.nvm/versions/node/v12.20.1/bin/npm
  npmPackages:
    webpack: ^5.33.2 => 5.33.2

References

  1. https://webpack.docschina.org/migrate/5/
  2. https://juejin.cn/post/6844904169405415432 待看
  3. https://juejin.cn/post/6922622067149897735
  4. 构建效率大幅提升,webpack5 在企鹅辅导的升级实践
  5. https://dongdaima.com/article/30465#/ 待删
  6. https://webpack.js.org/loaders/babel-loader/ webapck babel
  7. https://blog.csdn.net/weixin_33727510/article/details/93264765 待删
  8. https://www.cnblogs.com/sk-3/p/14147612.html 待删