你知道运行 npm run xxx 到底发生了什么嘛?不好意思 我知道

start

  • 今天准备午休的时候,刚躺到床上,不知怎得,突然想起最近看到的一篇文章标题:运行 npm run xxx 的时候发生了什么?
  • 当时只是看了一眼文章的标题,有那么一点点印象,但是等我仔细思考这个问题的时候,发现好像不是那么简单。
  • 后来啊,我越思考越精神,不行不午睡了,我要弄懂它!

问题拆分

命令 : npm run serve

问题一: 为什么我们可以在控制台输入npm还不会报错?

问题二: run是哪里来的?

问题三: serve又是哪里来的?

知识储备

首先要学会打开cmd窗口

  1. win + R键 输入 cmd 回车即可
  2. 文件夹目录输入cmd 回车即可
  3. 按住shift,在文件夹右键 =》在此次打开Powershell即可
    注释:cmd 和 Powershell 暂时可以为理解是一样的,打开后就是下面这个样子:

image.png

问题一 》》》为什么我们可以在控制台输入npm还不会报错?

比如说我在cmd窗口输入一个我的昵称 tomato,它会提示
'tomato' 不是内部或外部命令,也不是可运行的程序或批处理文件。

image.png

那我是不是可以反向理解,我们的npm它是 内部或外部命令,或者是可运行的程序或批处理软件其中一种呢?

这里我找了一下相关文章,解释cmd窗口中输入字符串后的逻辑:

  1. 它首先会判断这个文件名是否包含绝对路径。如果包含绝对路径,那它只会在绝对路径中寻找。此时如果没找到,直接报错。

image.png

  1. 如果不包含绝对路径,则它会在 cmd 所操作的目录下寻找。

image.png

  1. 如果没找到,就会在操作系统的内置命令中找。PS :我这里就演示了一下 cd、dir

image.png

  1. 如果还没找到,就会去环境变量 Path 中记载的目录中找到。如果再没找到,cmd 就会报错。

1788152656f668721418f1997b31b7a.png

image.png

打开环境变量操作步骤 :设置》系统》关于》高级系统变量》环境变量》系统变量》Path

到这里就基本清楚了,为什么cmd中能够执行npm了。

问题一总结

  1. 我们安装了nodejs,nodejs中又内置npm,所以安装了nodejs 就一起安装了npm;
  2. 在安装nodejs的时候,安装程序会把nodejs的安装路径写入到了环境变量 Path 中;
  3. 在我们cmd中输入npm的时候,它会依次匹配,如果前三步都没有寻找到的话,它会在环境变量 Path 中记载的目录下找是否有名字叫npm的可执行文件;
  4. 这个时候就会读取到我们 nodejs文件夹下面的 npm.cmd这个文件了;
    PS: 可以尝试着把这个npm.cmd文件剪切到其他文件目录,重新打开cmd窗口输入npm,你会发现npm也无法执行。

问题二 》》》 run是哪里来的?

犹豫不决,先看官方文档,npm官方文档地址
1653708952(1).jpg

问题二总结:(个人总结参考即可)

  1. npm run是npm自带的内置命令
  2. npm run可以用来执行当前目录下package.json中的scripts对象中的属性对应的命令。
  3. npm run后面没有加字符,那它会打印可执行的命令。
  4. 除了可以打 run,还可以敲rum, urn功能是一样的。

image.png

问题三 》》》 serve又是哪里来的?

由问题二的结论可以得知,serve就是我们在package.json中的scripts对象中定义的属性名,我们执行npm run serve其实就是在执行vue-cli-service serve

初始化好的vue2项目的配置文件

{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  },
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.15",
    "@vue/cli-plugin-router": "~4.5.15",
    "@vue/cli-service": "~4.5.15",
    "vue-template-compiler": "^2.6.11"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

问题四 》》》 衍生出来的问题vue-cli-service哪里来的?

我在控制台直接输入命令vue-cli-service serve 直接报错。提示'vue-cli-service' 不是内部或外部命令,也不是可运行的程序或批处理文件。

为什么我通过 npm run serve,可以执行 vue-cli-service serve呢?

别慌继续看文档:

image.png

我用我9级英语意译一下:(ps 仅供参考)

In addition to the shell's pre-existing `PATH`,
// 除了预先已经存在于命令行中的 环境变量PATH

`npm run` adds `node_modules/.bin` to the `PATH` provided to scripts.
// 在 npm run 这个命令中 会将(./node_modules/.bin)这个目录也添加到环境变量Path中 给脚本使用  

Any binaries provided by locally-installed dependencies can be used without the `node_modules/.bin` prefix.
// ./node_modules/.bin中的任何二进制文件都可以在,不拼接前缀`./node_modules/.bin`,供npm run使用。

我们去查看一下我们本地项目中的./node_modules/.bin目录,确实存在vue-cli-service可执行文件

image.png

所以我npm run serve实际执行的是./node_modules/.bin中的vue-cli-service.cmd文件,即

npm run serve
↓
npm run ./node_modules/.bin/vue-cli-service serve
# 这里解释一下为什么有三个同名文件

# unix 系默认的可执行文件,必须输入完整文件名 vue-cli-service 
# windows cmd 中默认的可执行文件,当我们不添加后缀名时,自动根据 pathext 查找文件 vue-cli-service.cmd 
# Windows PowerShell 中可执行文件,可以跨平台 vue-cli-service.ps1

总结

  1. npmcmd 窗口通过 环境变量Path中的路径 找到文件 npm.cmd 文件并执行;

  2. runnpm自带的命令,支持运行package.json中的scripts对象的属性;

  3. 同时 run 还会将 ./node_modules/.bin中的可执行的文件,添加到 Path 中,从而可以不用添加前缀./node_modules/.bin, 就给scripts对象中的脚本中使用

  4. servepackage.json中的scripts对象的属性名。

  5. 有的依赖包会向 ./node_modules/.bin中写入可执行文件。

  6. ./node_modules/.bin中文件名相同,但文件格式不同的可执行文件,是用来兼容不同系统的。

举一反三

  1. 我们全局安装的依赖会怎么样呢,我尝试了一下,全局安装的依赖会被安装在,nodejs安装的目录,部分插件也会生成以 .cmd 结尾的文件,例如vue-cli的脚手架;

image.png

  1. 其次,由上述内容我们可以知道 ,要卸载nodejs。除了在系统的控制面板卸载应用以外,Path中的环境变量也要清除,对应路径的软件包也要删除,才算卸载干净。

  2. 在执行npm run 的时候,我自己试验了一下,它会先在自身的./node_modules/.bin中的可执行文件匹配,如果没有匹配到,才会再去cmd环境中匹配。

  3. 其次我工作中,单一的nodejs版本并不适合所有业务需要,某些时候需要切换nodejs的版本用来维护不同的项目,所以就借用了工具nvm切换和管理nodejs版本。在我了解完 nodenpm 这两个命令在 cmd 中完整的执行过程之后,我去看了一下,我电脑的环境变量Path。又测试了一下,基本理解了 nvm 的工作原理:

  1. 它会将一个文件夹路径A,写入到环境变量Path中,供 cmd 访问。
  2. 每次切换nodejs版本的时候,它会把你设置的对应版本nodejs执行文件,拷贝到文件夹A中。
  3. 可以理解为每次切换nodejs版本的时候,其实就是不同版本的nodejs程序的复制粘贴。因为我们通过cmd使用nodejs都是访问路径A,所以路径A中的nodejs的版本是多少,我cmd中的node -v版本就是多少。

参考博客

  1. # Windows 中的环境变量 Path 的作用

  2. # 三面面试官:运行 npm run xxx 的时候发生了什么?

  3. # npm scripts 使用指南

end

  • 其实写到这里 我就对这种 .cmd 结尾的文件是如何运行的,产生了浓厚的兴趣,后面一定了解了解,再做详细说明。
  • 走了睡午觉去了。
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lazy_tomato

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值