npm run xxx 到底发生了什么?

575 阅读3分钟

自我理解

  1. 运行 npm run xxx 的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
  2. 如果没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx 就是安装到全局目录;
  3. 如果安装目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序;

实现原理

npm 实现的原理非常简单。每当执行 npm run,就会自动新建一个 Shell,在这个 Sell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。

Shell 是一个应用程序,它连接了用户和 Linux 内核(在Linux下,这个命令行程序叫做 Shell),让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。

比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将 PATH恢复原样。

这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha,只要直接写mocha test就可以了。

"test": "mocha test"

而不用写成下面这样

"test": "./node_modules/.bin/mocha test"

常见问题

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

  • 因为直接执行 vue-cli-service serve 会报错,因为操作系统中没有存在 vue-cli-service这一条指令,而你执行npm run xxx 的时候会多一个查找的操作,去查找xxx对应的可执行文件去执行

  • npm i 的时候,npm 就帮我们把这种软连接配置好了,其实这种软连接相当于一种映射,执行npm run xxx 的时候,就会到 node_modules/bin中找对应的映射文件,然后再找到相应的js文件来执行。

在node_modules/bin中 有三个vue-cli-service文件。为什么会有三个文件呢?

image-20220328113509420

这三个文件主要对应着三种不同的环境下的脚本文件

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

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

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

可以根据你当前所在的运行环境去执行相应的脚本文件,最终这几个脚本都会使用node 去运行 vue-cli-service.js这个 js 文件

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

参考链接