npm run xxx
时发生了什么大家都知道目前的 node 是捆绑 npm 的。npm 是 node 的依赖管理器,虽然它不是唯一的选择,我们还有 pnpm/yarn/cnpm/ni 。
但是,node的依赖管理器都是在解决 npm 的某个痛点。对于 npm 依赖声明文件package.json
本身是基本没有变化的。
npm run serve
npm run build
npm run xxx
npm run ...
他们都只是对 package.json
进行解析而已
下面我们举个例子看看:
npm run serve
//当执行这个指令时,其实就是运行json文件中的scripts下的serve
{
"name": "h5",
"version": "1.0.7",
"private": true,
"scripts": {
"serve": "vue-cli-service serve"
},
"dependencies": {
"axios": "^0.19.2",
"vuex": "^3.4.0"
},
"devDependencies": {
"node-sass": "^4.12.0"
}
}
vue-cli-service serve
而是使用npm run serve
如果直接在命令行中运行 如果直接在命令行中运行
这条命令,是不会从 node_modules 中查找可执行程序的。
因为 直接执行vue-cli-service serve
,会报错,因为操作系统中没有存在vue-cli-service
这一条指令。
那么我们解决了《为什么不能直接运行vue-cli-service serve
》,下面要解决《为什么是使用npm run serve
》
我们在安装依赖的时候,是通过npm i xxx
来执行的,例如 npm i @vue/cli-service
,npm 在 安装这个依赖的时候,就会node_modules/.bin/
目录中创建 好vue-cli-service
为名的几个可执行文件了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y2RG64fl-1650990608363)(
.bin 目录,这个目录不是任何一个 npm 包。目录下的文件,表示这是一个个软链接,打开文件可以看到文件顶部写着 #!/bin/sh
,表示这是一个脚本。
由此我们可以知道,当使用 npm run serve
执行 vue-cli-service serve
时,虽然没有安装 vue-cli-service
的全局命令,但是 npm 会到 ./node_modules/.bin
中找到 vue-cli-service
文件作为 脚本来执行,则相当于执行了 ./node_modules/.bin/vue-cli-service serve
(最后的 serve 作为参数传入)。
上述提到的软连接又抛出了一个新的问题:
.bin 目录下的文件表示软连接,那这个bin目录下的那些软连接文件是哪里来的呢?它又是怎么知道这条软连接是执行哪里的呢?下面我们会解释这个问题
从 package-lock.json 中可知,当我们npm i 整个新建的vue项目的时候,npm 将 bin/vue-cli-service.js 作为 bin 声明了。所以在 npm install 时,npm 读到该配置后,就将该文件软链接到 ./node_modules/.bin 目录下,而 npm 还会自动把node_modules/.bin加入$PATH,这样就可以直接作为命令运行依赖程序和开发依赖程序,不用全局安装了。
假如我们在安装包时,使用 npm install -g xxx
来安装,那么会将其中的 bin 文件加入到全局,比如 create-react-app 和 vue-cli ,在全局安装后,就可以直接使用如 vue-cli projectName 这样的命令来创建项目了。
所以总而言之:
就是说,npm i 的时候,npm 就帮我们把这种软连接配置好了,其实这种软连接相当于一种映射,执行npm run xxx 的时候,就会到 node_modules/bin中找对应的映射文件,然后再找到相应的js文件来执行。
软连接相当于一种映射,执行npm run xxx 的时候,就会到 node_modules/bin中找对应的映射文件,然后再找到相应的js文件来执行。