自我理解
- 运行
npm run xxx的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行; - 如果没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx 就是安装到全局目录;
- 如果安装目录还是没找到,那么就从 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文件。为什么会有三个文件呢?
这三个文件主要对应着三种不同的环境下的脚本文件
# 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 中可以做很多事情,例如读取并分析运行这条命令的目录下的文件,根据模板生成文件等。
参考链接