node版本8.x→16.x,前端维护火葬场,题目及办理方案总结 ...

锦通  金牌会员 | 2024-8-26 15:19:36 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

为了后续的工程开发,我需要升级我的node,在此之前我的node版本是8,这个版本太老了,从8升级到16的跨度太大,对于从前的许多项目,产生了非常多维护方面的题目,历时四天终于全部办理了,简单总结一下:
   1、依赖之间的版本辩论题目
2、node16.x与node-sass的版本辩论题目,进而引发node-sass与sass-loader的辩论、sass-loader与webpack的辩论题目等
3、各插件的版本辩论题目,比方file-loader与webpack的版本辩论题目
4、部门插件不再被官方维护,比方extract-text-webpack-plugin、uglifyjs-webpack-plugin等,需要找寻相关的替代品,并根据官方文档来做设置文件相关调解
5、部门插件升级导致语法变更报错题目
  题目总结起来比较清晰,但是实际维护需要大量的测试,尤其是不同版本的node对应着不同版本的开发依赖,而开发依赖可能会对应着大量插件上的辩论。网上的方案太过零散而且很多办理的不太规范,发起直接肝官方文档:
webpack官方文档
与其相关的插件也可以直接查阅文档。

  
dependencies

一样平常来说,这里的依赖关系不必再维护,只要环境能兼容即可,比方:
  1. "dependencies": {
  2.     "@babel/preset-es2015": "^7.0.0-beta.53",
  3.     "axios": "^0.18.0",
  4.     "echarts": "^4.2.0-rc.2",
  5.     "element-ui": "^2.4.11",
  6.     "global": "^4.4.0",
  7.     "vis": "^4.21.0",
  8.     "vue": "^2.5.2",
  9.     "vue-cookies": "^1.5.12",
  10.     "vue-router": "^3.0.1",
  11.     "vuex": "^3.0.1",
  12.     "vuex-persistedstate": "^2.5.4"
  13.   },
复制代码
如果使用npm i或一个个npm i 模块名的方式导入,很可能出现以下错误:
npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree。
无法分析依赖树,这是由于用户依赖的包版本与各个子项目依赖的包版本相互不兼容。
当把node升级到16.x以后,npm版本会升级为8.x,而在npm7以后install指令默认会以peerDependencies的方式去下载。
peerDependencies介绍(可略)

peerDependencies 在 package.json 中起到一个包含了项目里需要的所有的包或则用户正在下载的版本号雷同的所有的包的角色。接纳 peerDepenedency 来下载,就可以避免依赖库被重复下载的题目。比方:
   软件包“A”依赖于软件包“B”,但“B”不应该直接被安装在“A”中,而应该依赖于宿主应用程序或其他模块中已经安装的 “B” 版本。
  也就是说,当依赖中相互有辩论的时候,就会报错,导入失败。
办理方案

直接暴力使用指令npm install --legacy-peer-deps,但是需要注意,这里其实按我理解来看只是省略了一些相互的辩论,而不是办理辩论,在之前的项目并没有由于这些辩论而导致运行错误的环境下,直接使用这种方式还是很便捷的。
devDependencies维护

开发依赖的下载,通常使用的指令是npm install -D,在这里不光会出现依赖相互的辩论,如果使用--legacy-peer-deps也会出错,这是由于有一些与node版本紧密相连的依赖,直接暴力下载也会出错。
因此,发起直接修改package.json文件,将devDependencies中的node-sass、node-notifier、sass-loader、webpack等与node直接或间接相关的依赖先删除,实行npm install -D --legacy-peer-deps下载其他依赖。最后再逐步下载其他依赖。
题目

其中一个最棘手的开发依赖的维护,我的开发依赖如下:
  1. "devDependencies": {
  2.     "@babel/core": "^7.2.2",
  3.     "@babel/preset-env": "^7.2.3",
  4.     "autoprefixer": "^7.1.2",
  5.     "babel-core": "^6.22.1",
  6.     "babel-helper-vue-jsx-merge-props": "^2.0.3",
  7.     "babel-loader": "^7.1.5",
  8.     "babel-plugin-syntax-jsx": "^6.18.0",
  9.     "babel-plugin-transform-runtime": "^6.22.0",
  10.     "babel-plugin-transform-vue-jsx": "^3.5.0",
  11.     "babel-preset-env": "^1.3.2",
  12.     "babel-preset-stage-2": "^6.22.0",
  13.     "chalk": "^2.0.1",
  14.     "copy-webpack-plugin": "^4.0.1",
  15.     "css-loader": "^0.28.0",
  16.     "extract-text-webpack-plugin": "^3.0.0",
  17.     "file-loader": "^1.1.4",
  18.     "friendly-errors-webpack-plugin": "^1.6.1",
  19.     "html-webpack-plugin": "^2.30.1",
  20.     "node-notifier": "^5.1.2",
  21.     "node-sass": "^4.14.1",
  22.     "optimize-css-assets-webpack-plugin": "^3.2.0",
  23.     "ora": "^1.2.0",
  24.     "portfinder": "^1.0.13",
  25.     "postcss-import": "^11.0.0",
  26.     "postcss-loader": "^2.0.8",
  27.     "postcss-url": "^7.2.1",
  28.     "rimraf": "^2.6.0",
  29.     "sass-loader": "^7.1.0",
  30.     "semver": "^5.3.0",
  31.     "shelljs": "^0.7.6",
  32.     "uglifyjs-webpack-plugin": "^1.1.1",
  33.     "url-loader": "^0.5.8",
  34.     "vue-loader": "^13.3.0",
  35.     "vue-style-loader": "^3.0.1",
  36.     "vue-template-compiler": "^2.5.2",
  37.     "webpack": "^3.12.0",
  38.     "webpack-bundle-analyzer": "^2.9.0",
  39.     "webpack-dev-server": "^2.9.1",
  40.     "webpack-merge": "^4.1.0"
  41.   },
复制代码
重要出现的题目可以归结为两类:
   1、node-sass与node的版本辩论
2、node-sass版本升级后,造成的一系列版本辩论题目
  办理方案

需要根据版本对照表来下载对应的node-sass以及sass-loader版本:
1、node与node-sass的版本对照表

2、node-sass与sass-loader的版本对照表

我起首是使用npm install -D node-sass --legacy-peer-deps直接下载,默认版本非常高,到达10.x,我担心这个版本会造成太多题目,因此降低到了6.x,使用指令npm install -D node-sass@6.x --legacy-peer-deps即可。如果在下载时报了warning:

不必理会,后续根据peerDependencies来做版本的测试与修改(进步/回退),对应的sass-loader发起对照表格来限定,不要太高版本了,使用npm install -D sass-loader@10.x --legacy-peer-deps即可。
对于任何一个依赖,我们可以查看它的peerDependencies。
比方对于sass-loader,我们可以使用Ctrl+Shift+R查找package-lock.json中的peerDependencies:

很显然,我们需要更高版本的webpack,需要手动修改,在这里我将webpack升级为4.36.0版本。
插件版本辩论

以webpack为轴,还会继而引发更多的题目,比方html-webpack-plugin插件的peerDependencies显示其需要的webpack版本不超过4.x,以是需要进而更新各种插件,发起直接使用"webpack":来做全局搜刮,从而探求插件的版本辩论。
如果碰到了类似下面的warning,这时候不能不理会:

这说明我们的node版本无法到达要求,需要手动的降低版本,这种没有相关的文档,自己凭感觉降低版本,然后查看peerDependencies来做调试即可。
插件过期更新

在这里我统共有两个插件失效了,一个是extract-text-webpack-plugin,另外一个是uglifyjs-webpack-plugin,官方不再维护这两个插件,这两个插件的最高版本无法适配当前的环境(其实其他插件也曾经报错过,但是我把它们的peerDependencies对应的插件降低到最低版本,这两个是实在无奈只能弃用了,当然了不发起这样做,该换插件就换)
extract-text-webpack-plugin换成mini-css-extract-plugin

前面sass-loader对应的webpack版本最低就是4.36.0,无论我是否将node-sass以及sass-loader降低到极限最低版本,webpack的版本都无法降低到4.2.x,也就是说,这个插件必须要更新了。直接搜官方文档就可以看到该插件已经被mini-css-extract-plugin替代了:

对所有效到extract-text-webpack-plugin的地方举行改造:
1、utils.js
  1. // let ExtractTextPlugin = require('extract-text-webpack-plugin')
  2. let MiniCssExtractPlugin = require('mini-css-extract-plugin')
  3. function generateLoaders (loader, loaderOptions) {
  4.     const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
  5.     if (loader) {
  6.       loaders.push({
  7.         loader: loader + '-loader',
  8.         options: Object.assign({}, loaderOptions, {
  9.           sourceMap: options.sourceMap
  10.         })
  11.       })
  12.     }
  13.     // Extract CSS when that option is specified
  14.     // (which is the case during production build)
  15.     if (options.extract) {
  16.       // return MiniCssExtractPlugin.extract({
  17.       //   use: loaders,
  18.       //   fallback: 'vue-style-loader'
  19.       // })
  20.       return [MiniCssExtractPlugin.loader].concat(loaders)
  21.     } else {
  22.       return ['vue-style-loader'].concat(loaders)
  23.     }
  24.   }
复制代码
2、webpack.prod.config.js
  1. const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  2. const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
  3. const TerserJsPlugin  = require('terser-webpack-plugin')
  4. const webpackConfig = merge(baseWebpackConfig, {
  5.   minimize: true,
  6.   minimizer: [new TerserJsPlugin({}), new OptimizeCSSPlugin({})],
  7.   runtimeChunk: {
  8.     name: 'runtime'
  9.   },
  10.   module: {
  11.     rules: utils.styleLoaders({
  12.       sourceMap: config.build.productionSourceMap,
  13.       extract: true,
  14.       usePostCSS: true
  15.     })
  16.   },
  17.   devtool: config.build.productionSourceMap ? config.build.devtool : false,
  18.   output: {
  19.     path: config.build.assetsRoot,
  20.     filename: utils.assetsPath('js/[name].[chunkhash].js'),
  21.     chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  22.   },
  23.   plugins: [
  24.     // http://vuejs.github.io/vue-loader/en/workflow/production.html
  25.     new webpack.DefinePlugin({
  26.       'process.env': env
  27.     }),
  28.     new TerserJsPlugin({
  29.       terserOptions: {
  30.         compress: {
  31.           warnings: false
  32.         }
  33.       },
  34.       sourceMap: config.build.productionSourceMap,
  35.       parallel: true
  36.     }),
  37.     // extract css into its own file
  38.     new MiniCssExtractPlugin({
  39.       filename: utils.assetsPath('css/[name].[contenthash].css'),
  40.       // Setting the following option to `false` will not extract CSS from codesplit chunks.
  41.       // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
  42.       // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
  43.       // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
  44.       allChunks: true,
  45.       ignoreOrder: true,
  46.     }),
  47.     // Compress extracted CSS. We are using this plugin so that possible
  48.     // duplicated CSS from different components can be deduped.
  49.     new OptimizeCSSPlugin({
  50.       cssProcessorOptions: config.build.productionSourceMap
  51.         ? { safe: true, map: { inline: false } }
  52.         : { safe: true }
  53.     }),
  54.     new webpack.HashedModuleIdsPlugin(),
  55.     // enable scope hoisting
  56.     new webpack.optimize.ModuleConcatenationPlugin(),
  57.     // split vendor js into its own file
  58.     new webpack.optimize.CommonsChunkPlugin({
  59.       name: 'vendor',
  60.       minChunks (module) {
  61.         // any required modules inside node_modules are extracted to vendor
  62.         return (
  63.           module.resource &&
  64.           /\.js$/.test(module.resource) &&
  65.           module.resource.indexOf(
  66.             path.join(__dirname, '../node_modules')
  67.           ) === 0
  68.         )
  69.       }
  70.     }),
  71.     // extract webpack runtime and module manifest to its own file in order to
  72.     // prevent vendor hash from being updated whenever app bundle is updated
  73.     new webpack.optimize.CommonsChunkPlugin({
  74.       name: 'manifest',
  75.       minChunks: Infinity
  76.     }),
  77.     // This instance extracts shared chunks from code splitted chunks and bundles them
  78.     // in a separate chunk, similar to the vendor chunk
  79.     // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
  80.     new webpack.optimize.CommonsChunkPlugin({
  81.       name: 'app',
  82.       async: 'vendor-async',
  83.       children: true,
  84.       minChunks: 3
  85.     }),
  86.     // copy custom static assets
  87.     new CopyWebpackPlugin([
  88.       {
  89.         from: path.resolve(__dirname, '../static'),
  90.         to: config.build.assetsSubDirectory,
  91.         ignore: ['.*']
  92.       }
  93.     ])
  94.   ]
  95. })
复制代码
uglifyjs-webpack-plugin换成terser-webpack-plugin

同样查看官方文档,这里的切换很轻易,只需要把const UglifyjsJsPlugin = require('terser-webpack-plugin')换成const TerserJsPlugin = require('terser-webpack-plugin')即可,要求不高。
项目启动报错

代码编译成功,但是报了10%的waring:

直接根据提示去网上找办理方案全是亲一色的让我们修改localhost,该方案无法办理题目,因此直接去前端查看控制台输出:

办理方法:
1、语法:
exports 导出的东西需要 require 引入,export 导出的东西需要 import 引入
2、在.babelrc中将transform-runtime注释:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

锦通

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表