node版本8.x→16.x,前端维护火葬场,问题及解决方案总结

news2024/11/15 20:09:11

为了后续的工程开发,我需要升级我的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
    • peerDependencies介绍(可略)
    • 解决方案
  • devDependencies维护
    • 问题
    • 解决方案
  • 插件版本冲突
  • 插件过时更新
    • extract-text-webpack-plugin换成mini-css-extract-plugin
    • uglifyjs-webpack-plugin换成terser-webpack-plugin
  • 项目启动报错

dependencies

一般来说,这里的依赖关系不必再维护,只要环境能兼容即可,例如:

"dependencies": {
    "@babel/preset-es2015": "^7.0.0-beta.53",
    "axios": "^0.18.0",
    "echarts": "^4.2.0-rc.2",
    "element-ui": "^2.4.11",
    "global": "^4.4.0",
    "vis": "^4.21.0",
    "vue": "^2.5.2",
    "vue-cookies": "^1.5.12",
    "vue-router": "^3.0.1",
    "vuex": "^3.0.1",
    "vuex-persistedstate": "^2.5.4"
  },

如果使用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下载其他依赖。最后再逐步下载其他依赖。

问题

其中一个最棘手的开发依赖的维护,我的开发依赖如下:

"devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.2.3",
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-loader": "^7.1.5",
    "babel-plugin-syntax-jsx": "^6.18.0",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-plugin-transform-vue-jsx": "^3.5.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-stage-2": "^6.22.0",
    "chalk": "^2.0.1",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^1.1.4",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "node-notifier": "^5.1.2",
    "node-sass": "^4.14.1",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.8",
    "postcss-url": "^7.2.1",
    "rimraf": "^2.6.0",
    "sass-loader": "^7.1.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "uglifyjs-webpack-plugin": "^1.1.1",
    "url-loader": "^0.5.8",
    "vue-loader": "^13.3.0",
    "vue-style-loader": "^3.0.1",
    "vue-template-compiler": "^2.5.2",
    "webpack": "^3.12.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },

主要出现的问题可以归结为两类:

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

// let ExtractTextPlugin = require('extract-text-webpack-plugin')
let MiniCssExtractPlugin = require('mini-css-extract-plugin')

function generateLoaders (loader, loaderOptions) {
    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]

    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, {
          sourceMap: options.sourceMap
        })
      })
    }

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      // return MiniCssExtractPlugin.extract({
      //   use: loaders,
      //   fallback: 'vue-style-loader'
      // })
      return [MiniCssExtractPlugin.loader].concat(loaders)
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
  }

2、webpack.prod.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const TerserJsPlugin  = require('terser-webpack-plugin')

const webpackConfig = merge(baseWebpackConfig, {
  minimize: true,
  minimizer: [new TerserJsPlugin({}), new OptimizeCSSPlugin({})],
  runtimeChunk: {
    name: 'runtime'
  },
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true,
      usePostCSS: true
    })
  },
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new TerserJsPlugin({
      terserOptions: {
        compress: {
          warnings: false
        }
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true
    }),
    // extract css into its own file
    new MiniCssExtractPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css'),
      // Setting the following option to `false` will not extract CSS from codesplit chunks.
      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
      // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      allChunks: true,
      ignoreOrder: true,
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
        ? { safe: true, map: { inline: false } }
        : { safe: true }
    }),
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks (module) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    }),
    // This instance extracts shared chunks from code splitted chunks and bundles them
    // in a separate chunk, similar to the vendor chunk
    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
  ]
})

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注释:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2057172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python中的randint如何使用

python中的randint用来生成随机数,在使用randint之前,需要调用random库。random.randint()是随机生成指定范围内的整数,其有两个参数,一个是范围上限,一个是范围下限。 具体用法如下: import random print…

Redis系列之事务

概述 Redis事务提供一种将多个命令打包,然后一次性、按顺序地执行的机制,在事务执行的期间不会主动中断,服务器在执行完事务中的所有命令之后,才会继续处理其他客户端的其他命令。 三个重要的保证: 批量操作在发送E…

el-table中el-select俩列共用同一数据并且选择不能相同

需求:el-table中有el-select,el-select的下拉数据源是相同的,但是要同一行的俩列数据选择不相同,如果相同需要提示并且清空数据 1.效果 2.主要代码详解 主要是 change"handleChange(后人员, scope.$index, scope.row.new_use…

关于侵害用户权益行为app的通报的一些思考

8月16日上海市通信管理局官方微信公众号“上海通信圈”发布《上海市通信管理局关于侵害用户权益行为app的通报(2024年第一批)》。本次app通报为2024年第一批。内容显示本次共通报26款移动互联网应用程序涉及app和小程序。 应用来源:本次检测…

【深海王国】小学生都能玩的语音模块?番外1:ASRPRO控制继电器开关

Hi~ (o ^ ^ o)♪, 各位深海王国的同志们,早上下午晚上凌晨好呀~ 辛苦工作的你今天也辛苦啦(/≧ω) 今天大都督为大家带来语音模块的番外系列——ASRPRO控制继电器开关,帮你学会使用ASRPRO控制继电器开关电器元件,let’s go! 番外…

学习大数据DAY39 基于 hive 的 SQL语句

目录 hive 介绍以及应用 上机练习 hive 介绍以及应用 --查看数据库 show database db_hive --过滤查看数据库 show databases like db_hive*; --查看详情 desc database db_hive desc database extended db_hive; --查看表 show tables; --查看表列详情 desc dept…

小学二年级数学精选试题

小学二年级数学精选试题

leetcode 089 打家劫舍

leetcode 089 打家劫舍 题目 一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响小偷偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定…

【计算机网络】网络版本计算器

此前我们关于TCP协议一直写的都是直接recv或者read,有了字节流的概念后,我们知道这样直接读可能会出错,所以我们如何进行分割完整报文?这就需要报头来解决了! 但当前我们先不谈这个话题,先从头开始。 将会…

GlobalMapper-大疆的航点kmz转航线文件展示空间轨迹

0序: 在大疆遥控器或者司空2中设置航线,都是一个个的航点,如果把航点转为航线,在三维地球中显示其空间效果。用于分析和实际物体的距离,或者展示该航线都做了哪些方面的考虑。 如何把一堆点连城一条线? 本…

进程相关命令和函数

查询进程相关命令 ps aux 查看进程相关信息 1.就绪态、运行态 R 2.睡眠态、等待态 可唤醒等待态 S 不可唤醒等待态 D 3.停止态 T 4.僵尸态 Z 5.结束态 top 根据CPU占用率查看进程相关信息 kill 和killall kill和killall发送一个信号 kill -2 PID 15 发送信号PID对应的进程&…

又一实锤 美元丧钟敲响

文|琥珀食酒社 作者 | 积溪 咱们又要见证历史了 之前我说美元霸权快终结了 没想到马上又来了一个实锤 就在刚刚 “159个国家将采用金砖国家新支付系统“的消息 冲上热搜 据大毛媒体爆料 这个新支付系统 将在今年10月份上线 替代现有的swift系统 这是要挖…

nginx的详细介绍及配置

Nginx(发音为“engine X”)是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。Nginx以其稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。它最初由俄罗斯人Igor Sysoev编写,并于2004年首次公开发布。N…

解决旧版CMS内容管理无法登录的问题

最近遇到了输入正确的账户密码,旧版的CMS内容管理的平台提示登录成功却无法跳转的问题 遇到这种情况请不要慌!!! 请按照下面的步骤解决问题: 1.点击账号管理 2.点击右上角的返回旧版控制台 3.点击cloud1环境 4.点击扩…

财务会计与管理会计(十一)

文章目录 快速切换日记账余额SUMPRODUCT、LOOKUP函数应用 销售业绩分段统计表SUMPRODUCT函数的应用 自动打印发票签收单VLOOKUP函数的应用 快速切换日记账余额 SUMPRODUCT、LOOKUP函数应用 C2SUMPRODUCT((A5:A100B2)*C5:C100) D2SUMPRODUCT((A5:A100B2)*D5:D100) E4公式1&…

javaweb学习之HTML(一)

推荐学习使用网站 w3school 在线教程 认识HTML HTML(HyperText Markup Language)是超文本标记语言,它是一个用于创建网页和网页应用程序的标准标记语言。HTML文档由一系列的元素(elements)组成,这些元素通…

大模型日报|10 篇必读的大模型论文

大家好,今日必读的大模型论文来啦! 1.斯坦福推出大模型网络安全能力和风险评估框架 Cybench 用于网络安全的语言模型智能体(agent)能够自主识别漏洞并执行漏洞利用,有可能对现实世界造成影响。政策制定者、模型提供者…

海外媒体投稿:怎样在法国媒体发稿宣传中获得成功

法国是一个充满机遇的销售市场,而媒体发稿营销推广是企业在法国市场里扩张曝光度和提升知名度的有效途径。下面我们就共享如何运用低投资得到高收益的办法,帮助企业在法国媒体发稿推广过程中获得成功。 第一步:掌握目标群体在进行法国媒体发稿…

HCIP-交换实验

根据实验要求,完成实验内容: 实验拓扑图如下所示 : 搭建拓补图: LSW1,LSW2: [LS1]interface Eth-Trunk 0 [LS1-Eth-Trunk0]q [LS1]interface g0/0/3 [LS1-GigabitEthernet0/0/3]eth-trunk 0 [LS1]interf…

微信支付商家转账到零钱申请必过方案总结

商家在申请商家转账到零钱时总会遇到各种原因的驳回,不少商家不断的修改又产生新的驳回原因从而导致工期无限延长,本文根据我们上万次成功申请商家转账到零钱的经验整理,帮助商家可以快速过审: 准备工作和注意事项 - 确认主体资格…