您现在的位置是:网站首页> 编程资料编程资料
webpack4升级到webpack5的实战经验总结_javascript技巧_
2023-05-24
347人已围观
简介 webpack4升级到webpack5的实战经验总结_javascript技巧_
前言
最近接手了公司内部webpack相关的依赖包,于是打算优化一波。考虑到webpack5已经正式发布近两年,跟webpack相关的依赖包应该适配的差不多了,于是打算先把webpack4升级到webpack5,然后基于webpack5再进行优化。
升级前用的是 "webpack": "^4.42.1" ,升级后用的是 "webpack": "^5.72.1" 。
笔者采用的升级webpack的方法是先一键升级所有的依赖包,然后一个一个地去解决运行过程中的报错。
首先,全局安装npm-check-updates:
yarn global add npm-check-updates
然后在项目中执行 ncu -u ,这样项目的package.json会把所有的依赖包都更新到最新版本,然后执行 yarn 。升级完就可以开启漫长的debug之旅了。
terser-webpack-plugin语法报错
Invalid options object. Terser Plugin has been initialized using an options object that does not match the API schema.
- options has an unknown property 'cache'. These properties are valid:
object { test?, include?, exclude?, terserOptions?, extractComments?, parallel?, minify? }
原来的配置:
minimizer: [ new TerserPlugin({ cache: true, parallel: true, terserOptions: { mangle: false, // Note `mangle.properties` is `false` by default. }, }), ] 从报错来看,terser-webpack-plugin的配置属性发生了改变,现在已经没有 cache 这个选项了。
terser-webpack-plugin是用来压缩JavaScript代码的。不过webpack5已经自带了terser-webpack-plugin,如果说你用的是webpack5或者更高版本,同时还希望自定义配置,那么还是需要安装terser-webpack-plugin。
webpack4的时候可以通过terser-webpack-plugin的cache属性开启文件缓存。现在webpack5自身提供了持久化缓存机制,它能够将首次打包的结果缓存到硬盘中,等下次打包的时候就可以跳过一系类的耗时的操作,复用第一次的打包结果。可以通过以下配置开启持久化缓存:
cache: { type: 'filesystem', version: 'yourVersion' } 缓存默认保存路径是 node_modules/.cache/webpack。这里要注意每当我们修改了webpack配置,记得更新cache的version,否则可能会出现因为重用了缓存导致配置没生效的问题。
综上,最后代码修改如下:
cache: { type: 'filesystem', version: '3.8.1', }, optimization: { ... minimizer: [ new TerserPlugin({ parallel: true, terserOptions: { mangle: false, // Note `mangle.properties` is `false` by default. }, }), ], ... } fork-ts-checker-webpack-plugin语法报错
Invalid configuration object. ForkTsCheckerWebpackPlugin has been initialized using a configuration object that does not match the API schema.
- configuration has an unknown property 'reportFiles'. These properties are valid:
object { async?, typescript?, formatter?, issue?, logger?, devServer? }
fork-ts-checker-webpack-plugin 是在单独的进程上运行 TypeScript 类型检查器的 Webpack 插件。当文件发生改动需要重新转译和类型检查时,fork-ts-checker-webpack-plugin会开辟一个单独的进程去执行类型检查的任务,这样就不会影响 webpack 重新编译的速度。
原来的配置:
plugins: [ new ForkTsCheckerWebpackPlugin({ memoryLimit: 4096, tsconfig: PATH.appDirectory + '/tsconfig.json', checkSyntacticErrors: true, reportFiles: [`${PATH.appSrc}/**/*.{ts,tsx}`], }), ] fork-ts-checker-webpack-plugin从 4.1.3 升级到 7.2.11 ,这个plugin的API已经发生了改变。改成:
plugins: [ new ForkTsCheckerWebpackPlugin({ typescript: { memoryLimit: 4096, configFile: PATH.appDirectory + '/tsconfig.json', diagnosticOptions: { syntactic: false, semantic: false, declaration: false, global: false } }, }), ] diagnosticOptions选项用来设置哪些TypeScript语法需要检查。
IgnorePlugin报错
Invalid options object. Ignore Plugin has been initialized using an options object that does not match the API schema.
- options should be one of these:
object { resourceRegExp, contextRegExp? } | object { checkResource }
Details:
* options misses the property 'resourceRegExp'. Should be:
RegExp
-> A RegExp to test the request against.
* options misses the property 'checkResource'. Should be:
function
-> A filter function for resource and context.
IgnorePlugin的作用是忽略第三包指定目录,让这些指定目录不要被打包进去。比如moment包的locale文件夹包括了各国语言的目录,如果把所有语言都打包进去就会影响打包效率。
原来的配置:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
从报错来看,该plugin的语法发生了改变。改成:
new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment/, }) devtool报错
Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.devtool should match pattern "^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$".
BREAKING CHANGE since webpack 5: The devtool option is more strict.
Please strictly follow the order of the keywords in the pattern.
大概的意思是说:检查devtool的匹配,webpack5要求的匹配更严格。
原来的配置:
devtool: isEnvDevelopment ? 'cheap-module-eval-source-map' : false,
改成:
devtool: isEnvDevelopment ? 'eval-cheap-module-source-map' : false,
webpack-dev-server publicPath报错
Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options has an unknown property 'publicPath'. These properties are valid:
object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, setupExitSignals?, static?, watchFiles?, webSocketServer? }
这次webpack-dev-server从 "^3.11.2" 升级到了 "^4.9.0"。
publicPath用来设置项目跑在本地时,打包生成的文件所在的位置。
原来的配置:
devServer: { ... publicPath: appConfig.publicPath, ... }, 改成:
devServer: { ... devMiddleware: { publicPath: appConfig.publicPath, }, ... }, webpack-dev-server contentBase报错
Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options has an unknown property 'contentBase'. These properties are valid:
object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, setupExitSignals?, static?, watchFiles?, webSocketServer? }
contentBase用来设置项目跑在本地时,不由webpack打包生成的文件的位置。
原来的配置:
devServer: { ... contentBase: PATH.appDirectory, ... }, devServer的v4中contentBase迁移到了static下,并且static的默认值是path.resolve(process.cwd(), 'public') 。改成:
devServer: { ... static: [ { directory: PATH.appDirectory, }, ], ... }, webpack-dev-server disableHostCheck报错
Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options has an unknown property 'disableHostCheck'. These properties are valid:
object { allowedHosts?, bonjour?, client?, compress?, devMiddleware?, headers?, historyApiFallback?, host?, hot?, http2?, https?, ipc?, liveReload?, magicHtml?, onAfterSetupMiddleware?, onBeforeSetupMiddleware?, onListening?, open?, port?, proxy?, setupExitSignals?, static?, watchFiles?, webSocketServer? }
原来的配置:
devServer: { ... disableHostCheck: true, ... }, 改成:
devServer: { ... allowedHosts: "all", ... }, 移除 node.js polyfill
Module not found: Error: Can't resolve 'crypto' in '/xxx/node_modules/crypto-js'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "crypto": false }
webpack5 以前,webpack 会包含 nodejs 核心模块的 polyfill,这样的话,比如安装了一个crypto模块,那么就可以直接使用,因为 node 的polyfill会自动启动。现在,webpack5 移除了 nodejs 的 polyfill,无法再直接使用类似crypto的模块了。
如果你想要使用类似crypto的 nodejs 核心模块,有两种方法:
1.在 webpack 配置文件的resolve中配置fallback
module.exports = { ... resolve: { fallback: { "crypto": require.resolve("cry
相关内容
- elementUI中el-dropdown的command实现传递多个参数_vue.js_
- js中yield参数应用示例深入理解_JavaScript_
- 手把手带你安装vue-cli并创建第一个vue-cli应用程序_vue.js_
- 实现一个Vue版Upload组件_vue.js_
- vue elementui二次封装el-table带插槽问题_vue.js_
- JS实现Tab栏切换的两种方式案例详解_javascript技巧_
- Axios+Spring Boot实现文件上传和下载_javascript技巧_
- vue.config.js完整配置教程_vue.js_
- element中el-table中的el-input校验的实现_vue.js_
- uniapp实现附近商家定位的示例代码_javascript技巧_
点击排行
本栏推荐
