npm script 是记录在 package.json
中的 scripts
字段中的一些自定义脚本,使用自定义脚本,用户能够将一些项目中经常使用的命令行记录在 package.json
不须要每次都要敲一遍。node
必须开发者经常须要使用如下命令来统计项目中的代码行数:webpack
find src -name "*.js" | xargs cat | wc -l
开发者能够将其写入 package.json
中:git
"scripts":{ "lines": "find src -name \"*.js\" | xargs cat | wc -l", }
之后开发者只须要执行 npm run lines
就能够了,而不须要再去写那么长的命令行,这能够大幅提升效率。须要注意的是,由于命令是写在 json 文件中的,有些特字符须要进行转译,好比上面的双引号。web
PATH
npm scripts 不是简简单单地执行 shell 语句而已,在执行以前它会将 node_modules/.bin/
加入到环境变量 PATH
中,因此在 npm scripts 中能够直接使用那些存在于 node_modules/.bin/
中的可执行文件。shell
不少使用 mocha 做为测试框架的项目中都有这么一个 npm scriptnpm
"scripts":{ "test": "mocha" }
mocha 并无全局安装,它的命令行工具存在于 node_modules/.bin/
中,之因此可以访问到它,正是由于 npm 背后的这一操做才使得这样的命令可以正常执行,在 npm script 执行完成后,会从 PATH
中移除。json
在执行 npm run test
(后面会看到这能够简写为 npm test
) 的时候就等同于:gulp
./node_modules/.bin/mocha
对于上面的脚本 "test": "mocha"
若是但愿给 mocha 传入一些选项,好比但愿执行:框架
mocha --reporter spec
须要这样执行 npm test:ssh
npm test -- --reporter spec
须要使用两个短线将选项隔开,或者将选项直接写在 package.json
中:
"scripts":{ "test": "mocha --reporter spec" }
在 shell 中传入的参数都要使用 --
隔开,这个 --
被视做 npm run 命令参数的结束,--
后面的内容都会原封不动地传给运行的命令。
在 npm script 中存在两个钩子,pre
和 post
,就拿上面的 lines 脚原本说,它的钩子脚本就是 prelines
和 postlines
"scripts":{ "prelines": "node prelines.js" "lines": "find src -name \"*.js\" | xargs cat | wc -l", "postlines": "node postlines" }
执行 npm run lines
,会先执行 prelines
再执行 lines
以后再执行 postlines
。
还有一些 script 会在模块安装,发布,卸载等不一样的生命周期被执行。
prepublish, publish, postpublish:发布模块
preinstall, install, postinstall:安装模块
preuninstall, uninstall, postuninstall:卸载模块
preversion, version, postversion:在使用 npm version 修改版本号的时候执行
pretest, test, posttest:执行 npm test
的时候
prestop, stop, poststop:执行 npm stop
的时候
prestart, start, poststart:执行 npm start
的时候
prerestart, restart, postrestart:执行 npm restart
的时候
这些 script 会在不一样的时刻自动被执行,这也是为何 npm run test
能够简写为 npm test
的缘由了,在执行 npm test
的时候会以次执行 pretest
、test
和 posttest
,固然了,若是没有指定 pretest
和 posttest
,会默默地跳过。
还有 npm restart
这个命令比较叼,它不仅仅执行 prerestart
, restart
, postrestart
这三个,而是按下面的顺序来执行:
prerestart
prestop
stop
poststop
restart
prestart
start
poststart
postrestart
在执行 npm script 的时候还能够访问到一些特殊的环境变量,经过 process.env.npm_package_xxx
能够得到到 package.json
中的内容。好比 process.env.npm_package_name
能够得到到 package.json
中 name
的值 "sv"
。
{ "name": "sv", "version": "1.3.0", "description": "", "main": "index.js", "repository": { "type": "git", "url": "git+ssh://git@gitlab.com/wy-ei/sv.git" } }
经过 process.env.npm_package_repository_type
能够拿到值 "git"
。
另外能够经过 process.env.npm_config_xxx
来拿到 npm config 中的值。好比经过 process.env.npm_config_user_email
能够拿到 user.email
的值。
还有一个比较特殊的环境变量 process.env.npm_lifecycle_event
在执行不一样的 npm script 的时候这个值是不一样的,好比执行 npm run build
的时候,这个值为 build
,经过判断这个变量,将一个脚本使用在不一样的 npm script 中。
使用任何脚本语言编写的 npm script 均可以拿到环境变量,好比在 shell 中要想拿到只须要使用 $npm_config_user_email
就行了。不一样的脚本须要使用其自身获取环境变量的方法来读取环境变。
另外,这些环境变量只能在执行 npm script 的时候拿到,正常执行的 node 脚本是获取不到的。
在 npm script 经常用到一些模块中的可执行程序,好比 eslint,webpack 等,那么要如何来本身编写一个命令行工具能,让它能够在 npm script 中被调用。
新建文件 cli.js
,写入须要的逻辑。
console.log("This article is Awesome, isn't it?");
package.json
的 bin 字段中指定命令行文件名称和路径{ "bin": { "cli": "./cli.js" } }
当用户安装之后,经过 ./node_modules/.bin/cli
执行,会报错,缘由是目前 shell 不知道使用什么解释器来执行这些代码,为此须要在脚本上方指定解释器。
#!usr/bin/env node console.log("This article is Awesome, isn't it?");
上面这一行在全部脚本文件中均可以看到,它叫作 SheBang 或者 HashBang,详见 Shebang_(Unix)),这行代码是告诉 shell 使用何种解释器来执行代码。usr/bin/env
是一个程序,usr/bin/env node
会找到当前 PATH 中的 node 来解释后面的代码。
有了这三步,就开发出了一个 node 的命令行工具。当用户安装这个模块的时候,npm 会在 node_modules/.bin/
中建立文件,名为 package.json
中的 bin 指定的命令名,并连接至对应的脚本。此后就能够在 npm script 中使用它了。
多说两句,将上面的 #!usr/bin/env node
写入 JavaScript 文件第一行,不会报错。由于这是一个 UNIX 世界都认识的东西。经过 chmod +x cli.js
,你可使用 ./cli.js
直接执行它,由于这一行已经告诉 shell 使用 node 来执行它了。
早在今年 3 月,在网上看到不少帖子,涌现出一个观点,要使用 npm script 来代替 gulp 这样的构建工具,现在看到 npm script 的功能确实强大,利用 node 和 shell 咱们可以写出一些很实用的脚本,来解决手头的问题,并不必定须要利用 gulp,grunt 这样的东西。据统计,在 2015 年 gulp 以绝对的优点占据着 task runner 使用率第一的位置,而在 2016 年 npm script 的使用率提高的很是快。
不管如何,npm script 老是会出如今你天天的工做中,愿本文能助你搞懂 npm script,让 npm script 帮助你加快开发效率。