浅析有关运行npm run serve时发生了什么的5个问题出发解析npm run的执行原理

1、npm run xxx 的时候,首先会去项目的 package.json 文件里找 scripts 里对应的 xxx,然后执行 xxx 的命令,例如启动vue项目 npm run serve 的时候,实际上就是执行了 package.json 文件里 scripts 下的 serve 对应的 vue-cli-service serve 这条命令

2、那为什么不直接执行 vue-cli-service serve而要执行 npm run serve 呢?

因为直接执行 vue-cli-service serve,会报错,因为操作系统中没有存在 vue-cli-service这一条指令

3、那既然 vue-cli-service这条指令不存在操作系统中,为什么执行 npm run serve时,也就是相当于执行了 vue-cli-service serve ,为什么这样它就能成功,而且不报指令不存在的错误呢?

我们重点关注下这个问题:为什么执行 npm run serve时可以成功,而且不报指令不存在的错误呢?

因为我们在安装依赖的时候,是通过 npm i xxx 来执行的,例如 npm i @vue/cli-service,npm 在安装这个依赖的时候,就会在 node_modules/.bin/ 目录中创建好 vue-cli-service 为名的几个可执行文件了。

.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 作为参数传入)

4、.bin 目录下的文件表示软连接,那这个bin目录下的那些软连接文件是哪里来的呢?它又是怎么知道这条软连接是执行哪里的呢?

我们可以直接在新建的vue项目里面搜索vue-cli-service

可以看到,它存在项目的 package-lock.json文件中,从 package-lock.json 中可知,当我们npm i 整个新建的vue项目的时候,npm 将 bin/vue-cli-service.js 作为 bin 声明了。

注意:bin字段不是在自己项目的package.json文件里面,而是在库的源代码中的package.json里面,用于在安装时创建软链指向bin中的地址
在 npm i 安装时写入到了项目的 package-lock.json 里

所以在 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文件来执行。

5、刚刚看到在node_modules/bin中有三个vue-cli-service文件,为什么会有三个文件呢?

如果我们在 cmd 里运行的时候,windows 一般是调用了 vue-cli-service.cmd这个文件,这是 windows 下的批处理脚本。

所以当我们运行 vue-cli-service serve这条命令的时候,就相当于运行 node_modules/.bin/vue-cli-service.cmd serve

然后这个脚本会使用 node 去运行 vue-cli-service.js这个 js 文件,由于 node 中可以使用一系列系统相关的 api ,所以在这个 js 中可以做很多事情,例如读取并分析运行这条命令的目录下的文件,根据模板生成文件等

unix 系默认的可执行文件,必须输入完整文件名
vue-cli-service

windows cmd 中默认的可执行文件,当我们不添加后缀名时,自动根据 pathext 查找文件
vue-cli-service.cmd

Windows PowerShell 中可执行文件,可以跨平台
vue-cli-service.ps1

6、总结:

(1)运行 npm run xxx的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;

(2)没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx就是安装到到全局目录;

(3)如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序。

二、当输入 npm run 后发生了什么

在前端开发的工作当中,使用 npm run dev 的命令启动本地开发环境,是再正常不过的事了。那么,当输入完类似 npm run xxx 的命令后,究竟是如何触发各种构建工具的构建命令以及启动 Node 服务等功能的呢?

首先我们知道,Node 作为 JavaScript 的运行时,可以把 .js 文件当做脚本来运行,像这种: node index.js
当我们使用 npm 来管理项目时,会在根目录下生成一个 package.json 文件,其中的 scripts 属性,就是用于配置 npm run xxx 命令的,比如我有如下配置:

// package.json
{
  // ...

  "scripts": {
    "start": "node ./src/index.js",
    "build": "react-scripts build",
  },
  // ...

}

当执行 npm start 时,对于 npm 来说,相当于执行 npm run start ,则映射为 scripts 属性下的 start 命令,即

npm start
相当于
npm run start
相当于
node ./src/index.js

这个比较好理解,就是直接使用全局安装的 Node 命令来执行了 ./src 目录下的 index.js 文件而已。

如上面类似,执行 npm run build 即相当于执行 react-scripts build 命令。这个命令,是使用 create-react-app 搭建 React 项目时默认配置的。与 Node 不同, react-scripts 并没有全局安装,怎么就能直接执行呢?

这时我们不妨看一下,使用 create-react-app 搭建的项目(使用 vue-cli 搭建的项目也一样),在 npm install 后,其 node_modules 目录下面的样子:

如图可以看到有一个 .bin 目录,这个目录不是任何一个 npm 包。目录下的文件,右面都有一个小箭头(VS Code 上这样显示),表示这是一个软链接,打开文件可以看到文件顶部写着 #!/user/bin/env node ,表示这是一个通过使用 Node 执行的脚本。

由此我们可以知道,当使用 npm run build 执行 react-scripts build 时,虽然没有安装 react-scripts 的全局命令,但是 npm 会到 ./node_modules/.bin 中找到 react-scripts.js 文件作为 Node 脚本来执行,则相当于执行了 ./node_modules/.bin/react-scripts build(最后的 build 作为参数传入)。

npm run build
相当于
./node_modules/.bin/react-scripts build

前面说过, react-scripts 是一个软链接,那么它的指向是哪里,又是怎么来的呢?

我们可以在 node_modules 目录下,直接找到 react-scripts 包,查看其目录结构和 package.json 如下:

package.json 中可知,这个包将 ./bin/react-scripts.js 作为 bin 声明了。所以在 npm install 时, npm 读到该配置后,就将该文件软链接到 ./node_modules/.bin 目录下,而 npm 还会自动把node_modules/.bin加入$PATH,这样就可以直接作为命令运行依赖程序和开发依赖程序,不用全局安装了。

假如我们在安装包时,使用 npm install -g xxx 来安装,那么会将其中的 bin 文件加入到全局,比如 create-react-appvue-cli ,在全局安装后,就可以直接使用如 vue-cli projectName 这样的命令来创建项目了。

第二节来源于:https://juejin.cn/post/6971723285138505765

还有这篇文章,可以学一下:https://juejin.cn/post/7025908145650139144

Original: https://www.cnblogs.com/goloving/p/16306638.html
Author: 古兰精
Title: 浅析有关运行npm run serve时发生了什么的5个问题出发解析npm run的执行原理

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/547517/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球