运行 npm run xxx 的时候发生了什么?。npm run serve问题一: 为什么我们可以在控制台输入npm还不会报错?
问题二: run是哪里来的?
问题三: serve又是哪里来的?
首先要学会打开cmd窗口
cmd 回车即可cmd 回车即可shift,在文件夹右键 =》在此次打开Powershell即可
npm还不会报错?比如说我在cmd窗口输入一个我的昵称 tomato,它会提示
'tomato' 不是内部或外部命令,也不是可运行的程序或批处理文件。

那我是不是可以反向理解,我们的npm它是 内部或外部命令,或者是可运行的程序或批处理软件其中一种呢?
cmd窗口中输入字符串后的逻辑:
cmd 所操作的目录下寻找。
cd、dir
cmd 就会报错。

打开环境变量操作步骤 :设置》系统》关于》高级系统变量》环境变量》系统变量》Path
到这里就基本清楚了,为什么cmd中能够执行npm了。
npm.cmd这个文件了;npm.cmd文件剪切到其他文件目录,重新打开cmd窗口输入npm,你会发现npm也无法执行。run是哪里来的?犹豫不决,先看官方文档,npm官方文档地址

npm run是npm自带的内置命令npm run可以用来执行当前目录下package.json中的scripts对象中的属性对应的命令。npm run后面没有加字符,那它会打印可执行的命令。run,还可以敲rum, urn功能是一样的。
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呢?
别慌继续看文档:

我用我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可执行文件

所以我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
npm 是 cmd 窗口通过 环境变量Path中的路径 找到文件 npm.cmd 文件并执行;
run 是npm自带的命令,支持运行package.json中的scripts对象的属性;
同时 run 还会将 ./node_modules/.bin中的可执行的文件,添加到 Path 中,从而可以不用添加前缀./node_modules/.bin, 就给scripts对象中的脚本中使用
serve 是package.json中的scripts对象的属性名。
有的依赖包会向 ./node_modules/.bin中写入可执行文件。
./node_modules/.bin中文件名相同,但文件格式不同的可执行文件,是用来兼容不同系统的。

其次,由上述内容我们可以知道 ,要卸载nodejs。除了在系统的控制面板卸载应用以外,Path中的环境变量也要清除,对应路径的软件包也要删除,才算卸载干净。
在执行npm run 的时候,我自己试验了一下,它会先在自身的./node_modules/.bin中的可执行文件匹配,如果没有匹配到,才会再去cmd环境中匹配。
其次我工作中,单一的nodejs版本并不适合所有业务需要,某些时候需要切换nodejs的版本用来维护不同的项目,所以就借用了工具nvm切换和管理nodejs版本。在我了解完 node 和 npm 这两个命令在 cmd 中完整的执行过程之后,我去看了一下,我电脑的环境变量Path。又测试了一下,基本理解了 nvm 的工作原理:
- 它会将一个文件夹路径A,写入到环境变量Path中,供
cmd访问。- 每次切换nodejs版本的时候,它会把你设置的对应版本nodejs执行文件,拷贝到文件夹A中。
- 可以理解为每次切换nodejs版本的时候,其实就是不同版本的nodejs程序的复制粘贴。因为我们通过cmd使用nodejs都是访问路径A,所以路径A中的nodejs的版本是多少,我cmd中的node -v版本就是多少。
.cmd 结尾的文件是如何运行的,产生了浓厚的兴趣,后面一定了解了解,再做详细说明。