如何防止 Node.js 频繁“修车”

发布于 1周前 作者 caililin 来自 nodejs/Nestjs

如何防止 Node.js 频繁“修车”
如题,我很少能够顺利的跑起来一个 Node.js 项目,每次都会遇到各种各样的包管理引入的坑。
有什么 Node.js 最佳实践能让我们少修点车?

98 回复

放弃不了,生态过于繁荣。估计是全球第一大编程语言生态。

写 dockerfile ,构建过程都交给 CI 流水线呗,全程自动化的构建才能保证任何人都可以重现

碰到这种单体项目我都是直奔 dockerfile 去的,最复杂的应该是接口有相互依赖关系的多语言分布式项目,要是数据库迁移都没有那才叫酸爽

想多了,2017 年我放弃 NodeJS 转投 Scala 才知道什么叫真正的繁荣(指 JVM )

“各种各样包管理引入的坑”
这点展开说说?想了解了解

项目里不是有 package-lock 、yaml-lock 、pnpm-lock 么

说错了,没有 package-lock 、yaml-lock 、pnpm-lock 么

#8 是想问你具体遇到过哪些坑,最佳实践我说不上啥,但针对具体的坑也许能说一两句,你丢个 stackoverflow 链接就很没意思了

实在太坑了,我一个项目里面有楼上这位仁兄说的 lock file ,但该出错照样出错。我就是写几行 example code ,结果是包引入的包没有 XMLHttpRequest 。
然后我刚刚又回去修车了,找到了这个链接看得我莫名奇妙的。https://stackoverflow.com/questions/32604460/xmlhttprequest-module-not-defined-found

#10 xhr 是浏览器环境下提供的一个全局对象,你是 nodejs 环境没有这个也很正常,如果是安装的某个包依赖 xhr ,那应该看看包有没有说明运行环境是否仅限浏览器

几年前开始没人维护并且项目还不规范的话,才能遇到吧。我感觉我去找的开源项目都挺容易跑起来的,有问题的也比较快就能解决。

试试多学习下前端知识?

不知道 NodeJS 项目是来自 GitHub 还是哪里,如果是 Github ,一般会有开发文档

宇宙中的物体质量排名:太阳 ,中子星,黑洞,node_modules ,新疆切糕

不维护的项目跑不起来也可以理解

package 中全部直接版本号写死
"helmet": “5.1.1”

先学习下基础知识,再来用会少走很多弯路。

npm 依赖确实是个大坑,冷嘲热讽要求学基础的是什么情况
学得好的,能否帮我优雅解决下这个问题? https://www.v2ex.com/t/870920


看头像和名字有点像多年前 NodeJS 群网友

npm 确实坑
期待 node 有 xhr 的人和 npm 谁更坑 我不好说

没有冷嘲热讽,遇到未知的问题,要学会进入源码中调试,还有环境问题,如果没有使用容器的话,Linux 、Mac 、Win 可能会有不一样的效果,可能是第三方包的 bug ,也可能是环境问题,也有可能是编译配置问题

用 yarn 和 yarn.lock
npm 安装依赖的坑主要在好好的跑 npm install ,后台跑起来一堆 python ,cmake 在跑编译,从 github 下载二进制,卡在和 js 无关的东西上
js 的部分跑不起来看打断点看 log 还是很好解决的吧

你这句话里引入了两个包管里器( yarn 和 npm ),两门编程语言( python 和 js ),一个构建工具( cmake )。
出了问题最容易搞定的恐怕是 cmake ,其次是 python 。

你确定? MDN 可没教过你怎么修 npm 的车吧,另外就是你所谓的基础知识在哪里?整个 nodjs 官网也没教你怎么修车或者避免翻车。



python 也有这个问题,好好地安装一个 cryptography 包,结果开始用 cargo 进行编译了。

https://github.com/pyca/cryptography/tree/main/src/rust

我觉得是这些语言的社区有问题,光想着用 C/Rust 重写关键组件提供性能了,C 代码的依赖怎么管理,完全提供合适的解决方案。

#27 s/完全提供 /完全没想着提供 /

不熟悉当然很容易踩坑啊
npm 那个依赖包的版本
带^的比如^1.8.18 ,不是锁定在这个版本,而是会安装小版本的更新,然后里面就可能会有 break change
所以上面有一楼回复让你把版本前面的符号去掉就锁定这个版本了

npm 确实坑
期待 node 有 xhr 的人和 npm 谁更坑 我不好说

#19
你遇到的问题一般 package-lock/yarn.lock 就能解决,可以锁住主动安装的依赖版本以及依赖的依赖版本,看文中描述应该是一开始没用。
更进一步可以考虑依赖预打包,直接把某个依赖以及它的依赖打成一个 js 文件,然后加到 git 中管理版本。这种情况下除非手动更新,否则不会被影响。

依赖都是版本问题导致的,比如 node-sass 经常会出现,固定一个版本后基本就好了,好奇别的语言不会出现类似的问题吗

如果是 npm 的问题,就去 npm 的官网或 issue 里找。如果是包的问题就去具体包的仓库里找答案。怎么使用搜索引擎也是一种基础知识。

抱歉,没有时间。

谢谢回复,礼貌待人是一种社会生存基础知识。已拉黑。

还遇到过本地的一个项目,之前都好好的,没有任何修改,过了两个月,npm run 就报错,改了一堆依赖才解决……

> 好奇别的语言不会出现类似的问题吗

我对 go 熟悉一些,我觉得 go 的依赖管理做的比 python/nodejs 好太多了



1. golang 自动锁定了版本,当你从 gihtub clone 一个项目下来以后,如果不手动升级,go mod tidy 不会自动给你升级

2. golang 中虽然也使用 cgo 的库,但大部分能用 go 重写的都用 go 写了。很少遇到像 python 的 confluence-kafka 这种依赖一个 C 库( librdkafka ) 的项目(这个 C 库需要你用 apt / yum 的方式安装,控制版本很困难,很容易破坏系统的环境)。https://github.com/confluentinc/confluent-kafka-python/blob/master/src/confluent_kafka/src/confluent_kafka.h#L23
3. golang 所有项目的依赖都存放在 GOPATH/pkg/mod/ 中,不会像 npm 那样产生 node_modules 黑洞

就是报错,啥原因咱也不知道

感谢回复,但是可能对我来说不是好办法。首先我们无论 dev 还是生产环境都是开启 lock 的,但并没有阻止问题。如果转 yarn 的话也许是个办法(还未测试),但小项目还好,大项目转恐怕未必会很顺利,npm/pnpm 兼容度足够高了吧,仍然有些项目不支持 pnpm-或者你需要手动解决很多依赖问题,得不偿失。
依赖打包这个是能解决, 但是太不优雅了,我们还是考虑的锁定版本方案

我这边说 npm install 是指代 npm script 的名称,实际使用中你应该使用固定的 npm 管理工具 npm 、pnpm 、或 yarn 。
python 、c++ 不是我引入的,是 npm 的包引入的,以 npm 哲学黑盒引用的哲学是不需要关心包的实现的,但它在这些依赖其他语言的编译出错的时候是几乎不可能 debug 的。

用 pnpm 之后基本问题少了
有个小妙招是,尽量用 js 库,避免 native 库

你是怎么做到的? 我很少运行不起来一个 nodejs 项目,一般没啥问题。能经常遇到问题你也算很厉害了。我好像遇到的少数跑不了的情况是,部分依赖包更新了版本,且不做向后兼容。这个时候需要自己指定依赖的安装版本才行。

node_modules.7z

你还别说 yarn3 就可以将依赖和代码一同提交(将每个依赖都压缩成 zip )


github 上面一些远古项目和野鸡项目(指个人开发者临时发电搞的轮子, 然后几年不更新)还是很容易出现这种情况的. 真的是 npm i 磕磕碰碰的跑完, 然后 run dev 跑不起来那种.
不过绝大部分比较知名的包一般都没这种情况, 其实是跟维护人有关, 有些开发者就喜欢乱定版本号, 把破坏性更新弄到小版本里面, 把功能更新弄到补丁版本, 没眼看

我真的很少遇到 node 项目跑不起来的,不过一般一个项目最近一次提交是 1,2 年前的我就不看了

node js 包管理就是碰运气,node modules 文件夹删掉后遇到什么奇怪问题都有可能

包 lock 了,node 和 npm 版本最好也要 lock ,或者至少在 README 中说明首次开发时使用的版本。我司项目就只能用 node 12 跑,14 就不行 [doge]

太先进了,我司项目只能用 node10 跑。有意思的是 codesandbox 也只能用 node10 跑。。之前去研究里面的编译咋搞,clone 下来本地跑来着。说明多知名的项目都有尾大不掉的问题

提高自身姿势水平即可极大缓解

最简单的,你把 node modules 直接干到代码版本管理里。

只要你们组长和 IT 没把你打死,那你就永远不会出问题。

直接下个压缩包吧,
包管理不锁版本真的是傻逼设计

做前端都是娱乐的,哪有什么稳定靠谱可言 )逃。。

是时候使用新标准双端兼容的 fetch 了

go ,php ,nodejs 都在用,的确 go 的包管理最好。

nodejs 最大的问题是过两个月跑不起来了,需要修依赖。

php 的 composer 同类问题也开始多起来。

pnpm 解决大部分这类问题。当然 node 版本也有关系

修车也是一种技能,很多牛人在比较差的车上,不停的修,领悟的新的思维范式,于是就诞生了另一个破车。

刚刚写了 2 天 node.js (本人多年 C++、Go 开发经验),发现这玩意写小东西的开发效率真是高,但是它能玩出来的奇技淫巧比人人诟病的 C++还多

git 提交 package-lock.json 锁定包的版本肯定不会出问题
要升级包自己删掉 package-lock.json 然后手动更新版本



有一天我看 chrome 的源码, 发现 chrome 团队就是这么做的。

node_modules 虽然有缺点,但不至于每次都被黑,现在不管是 pnpm\npm\yarn 都优化了很多。只能说还不够熟练。

我看 op 可能是运行一些老项目,老项目就要用老版本的 node 运行的,npm install 失败 切到 node8 试试先

我觉得还是要区分一下 nodejs 和 浏览器的 js
很多人都以为这两个是一个东西,混着玩

自己写东西的话就全部最新,一般都不会出问题。
接手别人的项目,就要确定好 node 环境和依赖版本了

依赖的包太多,版本冲突太多,给包升级太费劲,各种修

执行 npm i 的时候如果已经有 package-lock.json 文件,就会按照 package-lock.json 的版本号,所有包都安装指定版本,如果没有,那么会按照 package.json 安装符合版本清单的最新版本
所以只要提交 package-lock.json 就好了

依赖避免不了这个问题

A 包需要 引入 B:1.0, C:1.2

换了 win ,键盘还没熟悉老是提交评论,反正意思就那么个意思,A 包引用 B 包,然后 B 包又依赖 C,D,E,F,G 包,然后你们的项目依赖 A ,也以来 C 和 D ,但是版本又和 B 以来的不一致,甚至不兼容。

楼上几位口口声声说要先学习一下什么的,那这些学习资料在哪里呢?人家 cmake 还有个手册,整个 nodejs 官网就是让你装个 npm ,然后吹嘘一下 nodejs 彩虹屁,再粗浅的给介绍下 async 。
本来想着微软搞得 typescript 会解决很多问题,但他们实际上力气使错方向了。javascript 这门语言的问题远远没 npm 这么糟糕。typescript 的引入带来了更多的问题。我最经常遇到的一个问题是,当你跳转到一个函数定义时要么是看不懂的机器压缩代码,要么是无法区分这到底是 typescript 还是 javascript 。

还有 xhrhttprequest 这个问题,明明这个库在一个 nodejs 项目里面可以用,用到另一个库时报错说我引入了 xhrhttprequest 这个东西。

lock 那么稳翻车的就不会这么多了,多层依赖的你试试能锁几层

我现在用的 shrinkwrap 锁定似乎有效 你可以试试

你要自己看包使用的 dependencies ,像 xhrhttprequest 是浏览器端才有的 API ,如果用在非浏览器端肯定会出错

npm 的问题自然是去 npm 的官网 docs.npmjs.com 找啊

这么简单的问题一搜肯定知道。楼上这帮傻子还以为我是单纯的被这个问题坑到才吐槽 nodejs 的问题。但问题是我没用到,别人的库用到了。然后别人的库也是个 nodejs 项目。

你是想把所有 vue 的版本都锁到某个版本吧?这么做有点风险。不过如果你们用的 webpack ,可以在 resolve 里强行都指到你想要的 vue 版本

建议换 deno 或者换语言

昨天删除 node modules 后重新 install ,结果就出问题了,问题就出在这里啊,因为 package.json 里是^1.0.0 这样的,意思是大于 1.0.0 的版本。你写死就没这些问题了。
第二个问题就是你们用 vue3 来生产没有 vue2 稳,就像服务端用的最多的还是 java8 一样,用 java18 自然没有 java8 稳。

让你学基础知识不是冷嘲热讽,^1.0.0 会安装大于 1.0.0 小于 2.0.0 的版本。你学好这个,当重新安装依赖出问题你就知道咋回事,怎么处理。

我要是学了肯定学得会 我就是不学 谁花时间学谁是傻子

我可能确实学得不好,但是你至少把别人的经验看完再回复吧。
你把^1.0.0 改为 1.0.0 ,这样版本确实锁死了,但是
这个依赖 a 依赖了 b ,b 依赖了 c ,c 依赖了 d ,你难道以为 lock 能锁死每一层的版本?

你要是带着 nodejs 就是坨屎的心态,那肯定烦啊。其实固定好版本,有翻墙工具,问题不大。

你要是这么想的话,那确实有解决不完的问题,但是这个问题也不是无解,还有 lock 啊,这里边全了吧。最后你还能搭建私有 npm 服务器,这样肯定固定了。

还是那句话,如果你就带着这就是坨屎的心态,那你肯定烦,你大可以不干这个嘛。

楼上有老哥说 go 的包管理最好,这真的不是反讽吗? 🐶

简单来说,如果无法放弃就要学者接受,或者去学到更多知识去适应它,而不是单纯的吐槽来发泄情绪,我从来都认为发泄情绪除了引起争端没有任何好处。
另外,#75 的话应用你一句原话:
> 礼貌待人是一种社会生存基础知识。

node-sass 的问题主要是 windows 这边要求有 python 的对应版本和 visul studio 才能编译成功,现在换 dart-sass 没这个问题了。

不做也不行,毕竟前端必须跟 js/ts 打交道,而且我不是嫌 node npm 不好,只是觉得包管理不够完善,因为我也做多种语言开发,npm 的依赖问题是遇到最多的,不过现在通过其他方式锁定版本已经暂时不会烦这问题了。

我倒是想来找有什么手册或者指引能避免翻车或这有效修车。但发个贴一上来就是吐槽你修车技术不行,让你去学基础知识。此贴到现在为止没有一个人发过有效的教程或者指引,或者是你们口口声声说的基础知识。
另一个比较有意思的现象就是看下来,整个帖子都在修车。都是给车头疼医头,脚疼医脚的方案。要么就是吐槽你头不够铁,多撞几次就明白了。

那请你清晰的提出你的问题,而不是输出情绪。
你的态度决定了别人的态度

你不是会搜索吗?
https://stackoverflow.com/questions/34514363/how-to-use-xhr-api-in-node-js
人家都说了 xhrhttprequest 不能在 nodejs 里面用,别人在代码里写了 xhrhttprequest ,要么是做了条件判断,要么就是自己或三方库实现了这个功能

大概写了 5 年的 node 后端,除了依赖某些需要本地编译的 c 或 c++插件库,很少有 node_modules 重装跑不起来的,xhr 在 nodejs 环境里是没有的,nodejs 内置的的 api 可以参考官方文档 https://nodejs.org/en/docs/

更新依赖版本时看有没有 breaking change
只引用可靠的第三方库

确实一堆问题,npm install 成功率很低,不过对我来说更意外的是 npm install 经常会看到编译 C/C++代码…

非常少遇到跑不起来的。基本不翻车。

具体问题具体分析,哪里有什么一劳永逸的东西,没有银弹是几十年前提出的概念了,写个几年代码就应该懂这个道理

有 lockfile 为啥不直接 npm ci 呢。。npm install 肯定出错啊

xhrhttprequest 是浏览器的东西

针对如何防止Node.js频繁“修车”(即频繁出现错误或需要维护),以下是一些专业建议:

  1. 使用nodemon工具

    Node.js在开发过程中,频繁修改代码后需要重启服务器。使用nodemon工具可以自动监察代码修改并重启服务,减少手动重启的次数。安装并使用nodemon的示例代码如下:

    npm install --global nodemon
    nodemon practice.js
    
  2. 优化错误处理

    使用try/catch块和async/await语法处理异步错误,设置全局错误处理机制,捕获未捕获的异常和未处理的Promise拒绝,防止应用崩溃。示例代码如下:

    process.on('uncaughtException', (err) => {
        console.error('There was an uncaught error', err);
        process.exit();
    });
    
    process.on('unhandledRejection', (reason, promise) => {
        console.error('Unhandled Rejection at:', promise, 'reason:', reason);
        process.exit(1);
    });
    
  3. 性能优化

    使用最新的Node.js版本,减少阻塞代码,避免全局变量,使用高效的数据结构,利用集群和负载均衡提高吞吐量,使用缓存加快数据读取速度,以及使用流式处理节省内存。

  4. 定期监控与调优

    定期监控应用的性能,包括响应时间、内存使用和CPU负载等,及时发现并解决问题。使用性能分析工具识别性能瓶颈,并给出优化建议。

通过以上措施,可以有效减少Node.js应用的故障率,提高系统的稳定性和可靠性。

回到顶部