这里以vue-cli 4.0版本为例来说明,原理都一样。
-
JavaScript 是一种解释性语言,需要将其源代码提供给某些解释器才能运行。如果要使用 node.js 运行 JavaScript 文件,通常会运行以下命令:
//demo.js console.log('demo')
node demo.js
如果直接
cd
到demo.js
目录下 执行./demo.js
会抛出异常。如果希望 可以像运行二进制文件一样直接运行它,需要你对该文件有执行权限(例如,可以使用chmod u+x demo.js
设置)并设置了正确的Shebang
时,此方法才有效。Shebang
或hashbang
(#! 代码的英文发音)是文件的第一行,它告诉 OS 使用哪个解释器。//demo2.js #!/usr/bin/env node console.log('demo')
此时
cd
到demo.js
目录下,可直接执行./demo.js
注意:一定要写
./demo.js
。即使现在就在demo.js
的目录下,如果直接写demo.js
会抛出command not found: demo.js
-
package.json 中的bin字段,文档中的说明
A lot of packages have one or more executable files that they'd like to install into the PATH. npm makes this pretty easy (in fact, it uses this feature to install the "npm" executable.)
To use this, supply a
bin
field in your package.json which is a map of command name to local file name. On install, npm will symlink that file intoprefix/bin
for global installs, or./node_modules/.bin/
for local installs.For example, myapp could have this:
{ "bin" : { "myapp" : "./cli.js" } }
So, when you install myapp, it'll create a symlink from the cli.js
script to /usr/local/bin/myapp
.
If you have a single executable, and its name should be the name of the package, then you can just supply it as a string. For example:
{ "name": "my-program"
, "version": "1.2.5"
, "bin": "./path/to/program" }
would be the same as this:
{ "name": "my-program"
, "version": "1.2.5"
, "bin" : { "my-program" : "./path/to/program" } }
Please make sure that your file(s) referenced in bin
starts with #!/usr/bin/env node
, otherwise the scripts are started without the node executable!
大概意思就是说,如果在package.json文件中设置了bin: xxx.js
字段,当用npm安装一个包时,如果安装的是全局包,则会在prefix/bin
目录(通常这个目录是/usr/local/bin
)建立一个与xxx.js
对应的链接。如果安装的是一个局部包,则会在 ./node_modules/.bin
目录下建立一个与xxx.js
对应的链接。
去你的项目中查看webpack-dev-server这个包的 package.json中的bin字段,再去看./node_modules/.bin文件夹里查看,就会看到 有一个webpack-dev-sever.js 文件与 包里的原文件一样。
-
经过上述了解,现在看一下npm run
npm 脚本的原理非常简单。每当执行
npm run
,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。比较特别的是,
npm run
新建的这个 Shell,会将当前目录的node_modules/.bin
子目录加入PATH
变量,执行结束后,再将PATH
变量恢复原样。这意味着,当前目录的
node_modules/.bin
子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。所以 当把命令配置到 package.json 的scripts 里时,可以不加路径,直接执行那些链接到./node_modules/.bin里的文件,而且这些文件里,大都设置了
Shebang
,#!/usr/bin/env node
,所以不需要加 node 命令 就可以直接运行,而如果在终端 运行这些文件 就需要 cd到该文件的目录,才可以执行。