什么是npm脚本
{
// ...
"scripts": {
"build": "webpack"
}
}
package.json中scripts字段定义的每一个属性,都对应了一条脚本命令。上面代码定义了一个build脚本,执行npm run build,最终会使用webpack打包工程。
npm run build 背后发生的事情
在当前shell中执行npm run build时,系统会在环境变量PATH中寻找npm命令,npm命令是如何被找到的呢?
1. 寻找npm命令
Linux中命令其实是一个个的命令行程序,这些程序是分布在不同的众多目录中的。当命令行中输入一个命令的时,Linux需要到指定目录去查找命令对应的程序,而在PATH环境变量就记录这些目录。
安装nodejs时,会在PATH中添加nodejs的bin目录地址。
echo $PATH //可以查看PATH环境变量中记录了可执行命令所在的目录
// 输出结果:
/home/max/.nvm/versions/node/v14.17.6/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib
/home/max/.nvm/versions/node/v14.17.6/bin就是nodejs的bin目录地址。我们看看bin目录里有什么:
ll -a /home/max/.nvm/versions/node/v14.17.6/bin
...
lrwxrwxrwx 1 max max 38 Aug 31 2021 npm -> ../lib/node_modules/npm/bin/npm-cli.js
...
npm命令就在这里!
2. 执行npm命令
从上面的输出可以发现,npm是一个软链接指向npm-cli.js。这意味着执行npm时,实际执行了npm-cli.js文件。
npm-cli.js又是如何执行的?系统是如何知道使用node调用这个js文件呢?秘密就在npm-cli.js的第一行中:#!/usr/bin/env node。
#!叫做Shebang,常出现在类Unix系统的脚本中第一行,作为前两个字符,用于指明执行这个脚本文件的解释器。#!/usr/bin/env node会通知系统执行当前文件时,去PATH变量中所有的可执行命令目录中寻找node,类似前面寻找npm命令一样,找到node命令后就可以执行node npm-cli.js。到此为止,npm命令就被成功的调用了。
3. 调用webpack命令
webpack命令又在哪里?
默认情况下,我们会把webpack安装在当前工程中:npm i -D webpack,安装完毕后,会在当前工程的node_modules/.bin子目录中添加webpack命令。
npm run build是如何调用到node_modules/.bin目录中的webpack命令的?
每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。
比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,如此一来,我们就能调用到node_modules/.bin目录中的webpack命令了。执行结束后,再将PATH变量恢复原样。