npm install 都干了啥?

本文深入探讨了npm脚本的执行原理,解释了在不同环境下执行npm run命令时可能遇到的问题,尤其是在生产环境中。文章详细分析了npminstall过程,包括如何处理依赖包、创建软链接以及环境变量的设置,帮助读者理解为何某些情况下命令会失败。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

起因

本周我在将egg项目发布到生产环境之后,发现生产环境无法执行npm run start,提示如下图

摸索原因

script 命令是如何运行的?

作为一个前端工程师,我每天都会和各种环境打交道,经常在命令行执行cross-env NODE_ENV=dev等操作,突然有一天,我发现执行 cross-env NODE_ENV=dev 居然给我报错了?

检查了下原来是包没有使用全局安装,现在全局安装下npm i cross-env -g

嗯,果然不报错了,为啥啊?其实我们看上面的安装反馈就可以知道,全局安装会创建一个软连接

而使用项目依赖安装则不会有这步操作,则导致我们不能直接使用简写去执行命令。

那么问题来了,难道我所有需要在命令行执行的包都需要安装到全局,才能使用?

  1. 第一种方法,可以执行文件 ./node_modules/.bin/cross-env NODE=dev
  2. 作为一个懒人,当然不会用方法一啦,这个时候npm script就派上用场了

package.jsonscript中新增命令

"scripts": {
    "dev": "cross-env NODE=dev"
}
复制代码

执行npm run dev,看到这里,我想大多数人肯定会说,我靠,你说的方法我几百年前就知道了啊,还需要你来BB?

但是我想还是有一部分人和我一样不懂为啥使用npm script执行上面的命令就不会报错呢,难道也会创建软连接?其实是因为我们执行npm run的时候会将node_modules/.bin下面所有文件都添加到系统的环境变量中,这样在执行期间就可以使用缩写,等执行结束会自动删除这些环境变量

理清这些之后再来看我一开始说的问题,提示找不到模块,看了下 .bin 下面的代码

看样子是引入上级目录的index.js,但是我们并没有在上级目录找到该文件,导致报错,难道是别人的包写错了?当然这是不可能的,经过我不断的折腾,最后才发现!!!

其实我们在npm install的时候首先会下载对应资源包的压缩包放在用户目录下的.npm文件夹下,然后解压到项目的node_modules中,并且提取依赖包中指定的bin文件,在linux下会创建一条软连接,所以在linux下我们真正执行的是.bin文件夹下文件指向的文件,看下图。

而我遇到的问题就是执行npm installnpm start是两台机器,生产机上的文件实际上是从发布机 copy 过来的,导致软连接没了,所以才会报错。

吸取经验

从这么一个小小的问题就可以暴露出来,虽然我们每天都会执行npm script但是却对他的执行过程很模糊,导致遇到问题却找不到原因,最终在看了一些资料之后我总结了如下几个点。

总结

  1. npm install 会先查找本地已经下载过的包,不论版本是多少,找到了就不会去下载,所以如果要升级依赖,可以使用npm update或者显示安装npm install cross-env --save
  2. npm install 会先下载项目中的依赖包,然后下载依赖的依赖,这样就会导致,生成的文件是树形结构,并且存在许多重复的包,所以这个时候npm就会将依赖扁平化,将依赖的依赖提取到第一层,遇到版本号不一致的也会保留,遇到完全一致的就会删除。
  3. 最后还会提取依赖中的bin文件,windows操作系统生成cmd文件,linux系统生成软连接

查阅的资料

每一个小问题深入下去都会头皮发麻,学不动了

转载于:https://juejin.im/post/5cf7171e51882562de33c748

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值