咱们都很熟悉的,经过 npm run script-name
能够执行 package.json 中 scripts
对象配置的脚本。可是,你或许不知道下面这些知识。html
下文中 npm-scirpt 指 package.json
scripts
中配置的脚本命令。name-scirpt 指代某一个名字为 name 的脚本命令。node
当咱们使用命令 npm start
时,npm 会尝试执行 package.json scripts
中配置的 start 脚本命令。start-script 的默认配置为 "start": "node server.js"
。因此若是项目根目录下有 server.js 文件,那么经过 npm start
会直接运行 server.js 中的代码。python
除了 start-script ,当使用 npm start
命令时,npm 一样会尝试在 package.json scripts
中查找是否配置了 prestart,poststart 脚本命令。若是都配置了,npm 会按照如下顺序执行脚本。linux
相似的,npm test
, npm restart
, npm stop
都会按照以上的方式执行 scripts 中配置的对应脚本。同时 npm 会经过 npm_lifecycle_event 环境变量标识当前处于哪一阶段(所谓的生命周期)。好比,在 prestart-script 脚本执行阶段 npm_lifecycle_event 的值为 "prestart",start-script 阶段,值为 "start",即 package.json scripts
对象配置的脚本名字。webpack
以上是 npm 内置命令对应的脚本执行逻辑,对于咱们平时最熟悉的自定义脚本,以上逻辑一样适用。好比咱们配置了 "build": "webpack --mode=production"
,同时配置了 prebuild 以及 postbuild 脚本,当使用 npm run build
时,一样会依次执行 prebuild-script、build-script、postbuild-script。web
咱们配置的脚本命令,如 "start": "node server.js"
,node server.js
会当作一行代码传递给系统的 SHELL 去解释执行。实际使用的 SHELL 可能会根据系统平台而不一样,类 UNIX 系统里,如 macOS 或 linux 中指代的是 /bin/sh, 在 windows 中使用的是 cmd.exe。shell
既然是交给 SHELL 去解释执行的,说明配置的脚本能够是任意可以在 SHELL 中运行的命令,而不单单是 node 脚本或者 js 程序。即若是你的系统里安装了 python(或者说系统变量 PATH 里能找到 python 命令),你也能够将 scripts 配置为 "myscript": "python xxx.py"
npm
上面提到了在使用 npm run script-name
命令时,npm 会设置一个环境变量 npm_lifecycle_event。实际上 npm 还会设置不少环境变量,经过内置命令 npm run env
能够查看 npm 为脚本运行时设置的全部环境变量。 其中 package.json 中设置的全部字段,都会被设置为 npm_package_ 开头的环境变量。若是你的 packge.json 设置以下json
{
"name": "npm-demo",
"version": "1.0.0",
"script": {
"build": "webpack --mode=production"
},
"files": ["src"]
}
复制代码
则能够获得 npm_package_name
、npm_package_version
、npm_package_script_build
、npm_package_files_0
等变量。注意上面 package.json 中对象和数组中每一个字段都会有对应的环境变量。windows
不止 package.json,npm 相关的全部配置也会有 npm_config_ 开头的环境变量。你能够经过 npm config ls -l
查看全部配置,其中包括了全部 npm 默认配置,npmrc 文件中的配置,以及命令行中的配置项。
如:npm run dev --foo bar --dev
,此时npm 会添加两个配置项,设置 foo
为 bar 以及 dev
为 true,同时在 npm 脚本中能够经过环境变量 npm_config_foo
和 npm_config_dev
来访问。
如何使用这些环境变量? 若是你的脚本是 shell 脚本,能够直接经过对应的环境变量名获取变量值,若是是 node 脚本,能够经过 nodejs 中的全局变量 process.env
获取,好比获取项目版本号可使用 process.env.npm_package_version
。
另外,须要注意的是,即便在子目录下使用 npm run 命令,脚本也会在项目的根目录下运行。若是你想要区分在哪里使用的 npm run 命令,可使用 INIT_CWD 环境变量,该变量保存了 npm run 命令运行时目录的绝对路径。
上面提到了 npm-script 执行前会设置一些环境变量,其中很重要的一个环境变量是 PATH。npm 会将项目 node_modules/.bin
的绝对路径添加到环境变量 PATH 中。所以咱们能够在 npm-script 中使用项目本地安装的一些命令行工具。如上面设置的 build 脚本: "build": "webpack --mode=production"
。
只要咱们本地安装了 webpack,就能够在项目的 node_modules/.bin
路径下看到 webpack 可执行文件。又由于 node_modules/.bin
路径已经添加到 PATH 中,因此脚本运行时可以在 PATH 中找到 webpack 命令,从而顺利执行。
最后,为何 webpack 安装后,可以在 node_modules/.bin
路径下找到对应的可执行文件?能够查看 docs.npmjs.com/files/packa…