了解package.json中npm run命令的执行原理,以及直接运行shell命令

329 阅读2分钟

了解npm run

package.json文件中的script字段,可以定义脚本命令,通过npm run指令运行该脚本。

比如简单定义一个输出打印的shell脚本。

{
  "script": {
    "hw": "echo hello world!"
  }
}

执行npm run hw可以看到终端上打印出了hello world!

我们可以在很多工程项目中的package.json文件中看到定义了很多脚本命令,比如下面的:

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }
}

那么npm是如何启动这些脚本的呢?

执行原理

在执行npm run xxx指令的时候会创建一个shell,在shell中执行对应的脚本。

shell会将当前项目的可执行依赖目录(node_modules/.bin)添加到环境变量path中,当执行之后恢复原样(本地模块可以直接运行,不需要全局安装NPM模块)。也就是说脚本命令中的依赖名会直接找到node_modules/.bin下面的对应脚本,而不需要加上路径。

而在.bin目录下,一般针对一个依赖模块,会有3个可执行文件,没有后缀名的是对应Unix系的shell脚本,.cmd为后缀名的是windows bat脚本,.ps1为后缀名的则是PowerShell中可执行文件(可以跨平台),三者作用都是用node执行一个js文件。

比如说在项目中安装了vite依赖,由于vite依赖库中定义了bin,在安装后就会在项目的node_modules/.bin目录中简历一个软连接到vite依赖中。

打开vite看看那个文件里有啥:

前面提到,脚本命令中的依赖名会直接找到node_modules/.bin,在上图中可以看到这个软连接其实就是指向了node_modules/webpack中的bin目录。

可以直接写成如下:

"scripts": {"build": "webpack"}

而不需要写成

"scripts": {"build": "node_modules/.bin/webpack"}