拿下奇怪的前端报错:SyntaxError: Unexpected token ‘??=‘或‘xxx‘ - 浅谈Nodejs版本过高过低的部分问题
在前端开发时,如果同时维护多个项目,跨越的年度又比较大,难免会使用多个Nodejs版本。有时候版本不对,不仅仅是安装会报错
1 依赖无法安装
一般情况下nodejs又向后兼容较好(除了部分三方包),所以安装依赖的时候,高版本node安装低版本包问题不大,但低版本Node安装高版本需求的包就会有问题。
版本过低报错
vue-i18n@9.14.1: The engine "node" is incompatible with this module. Expected version ">= 16". Got "14.21.2"
解决办法
如果只是安装问题,简单的忽略node引擎即可
yarn install --ignore-engines
// npm 类似
2 前端开发环境启动不了
前端框架由于都是第三方维护,很少把兼容性做的特别好,因为主要还是优化的开发体验、效率、性能等收益比较大的。这时候,如果版本过高/过低,都会出错,对新入行的小伙伴肯定是一个挑战,记得之前带应届生-他们也被这折磨的很糟糕,要是当时写篇文收集下可能更好,当时我也是带人新手-真有些内疚。
2.1 Nodejs版本过低
Nodejs版本过低,经常会遇到这个预期外符号的报错(需要注意是否为启动报错,也就是internal包,而不是业务代码文件的错!),大多数情况下是nodejs版本过低,内部的语法不兼容。
如果是业务代码文件的错,要检查语法;如果是typescript,要检查是否配置了何时的lib、polyfile. 这时候还有个场景的报错,就是 ... is not a function , xxx is not callable ,也大概是缺少对应的api又没有打补丁或转义引起的 ~ 但如果是三方包,大概率就是nodejs版本问题
(node:24932) UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token
'??='
at Loader.moduleStrategy (internal/modules/esm/translators.js:149:18)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:24932) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:24932) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
SyntaxError: Unexpected token '??='
at wrapSafe (internal/modules/cjs/loader.js:1001:16)
at Module._compile (internal/modules/cjs/loader.js:1049:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:101:18)
at Object.<anonymous> (D:\projects\cloudpcadmin\modules\voi-server\node_modules\.prisma\client\index.js:25:5)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10
2.2 Nodejs版本高
版本过高,同样会有问题,尤其是第三方涉及到构建过程的那些。很多库都慢慢的消失了,尤其是一些以前c完成的库,不少被js或者rust等取代,高版本的nodejs使用高版本的v8引擎,这时候ffi很多接口可能就变了,于是你会发现类似node-sass一类的每个node版本有个对应的数字.node文件,高版本就推荐用sass了。
不只是Sass,涉及到在本机编译的非纯js实现的包都和node大版本深度绑定,注意下yarn install最后build阶段的那些包
Module build failed: Error: Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime (115)
For more information on which environments are supported please see:
https://github.com/sass/node-sass/releases/tag/v4.14.1
at module.exports (C:\Users\by4474\Documents\projects\cds-operate\node_modules\node-sass\lib\binding.js:13:13)
at Object.<anonymous> (C:\Users\by4474\Documents\projects\cds-operate\node_modules\node-sass\lib\index.js:14:35)
at Module._compile (node:internal/modules/cjs/loader:1358:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
at Module.load (node:internal/modules/cjs/loader:1208:32)
at Module._load (node:internal/modules/cjs/loader:1024:12)
at Module.require (node:internal/modules/cjs/loader:1233:19)
at require (node:internal/modules/helpers:179:18)
at getDefaultSassImpl (C:\Users\by4474\Documents\projects\cds-operate\node_modules\sass-loader\dist\index.js:198:10)
at Object.loader (C:\Users\by4474\Documents\projects\cds-operate\node_modules\sass-loader\dist\index.js:80:29)
3 推荐用docker搭建开发环境
3.1 nvm频繁切换容易出错
因为nvm是全局的,在多个项目联调时,切换到14版本,启动一个服务,然后切换到20启动一个vite项目,中途某个进程崩了或者起了新工程,又不知道切换到了什么版本。这时候如果重启下某个项目(偶尔会因为缓存hmr出问题等),又会遇到报错,大脑会卡一下
大脑有时候很懒也容易惯性思考,将之前正常的项目停止,立即重启,报错而无法启动,可能无法第一时间觉察到不知道啥时候改了什么全局配置,以为是刚改的代码、引入的包等有问题,很容易浪费时间
3.2 docker是一个完全独立的环境
docker是一个完全独立的环境,各个nodejs共存,只需要把整个工程目录作为虚拟盘挂载到容器内,再使用容器内的node/npm就不会出现不一致的问题了。详细的流程可以参考之前的文章
《拿下奇怪的前端报错》:nvm不可用报错`GLIBC_2.27‘‘GLIBCXX_3.4.20‘not Found?+ 使用docker构建多个前端项目实践_docker gclib2.27-CSDN博客https://blog.csdn.net/m0_38015699/article/details/142327130?spm=1001.2014.3001.5501
4 总结
稍微总结下
- 遇到难以理解的报错,首先确定报错文件,如果是项目文件就检查编译目标/语法
- 如果报错来自于nodejs的内部/第三方包,检查下nodejs版本
- 使用docker搭建开发环境是不错的选择
或许后面我会再出一起关于如何用docker搭建高可用的前端开发环境的,期待吧。喜欢就点赞收藏下哈
2cy
YU.H