众所周知,npm
是工程师们基于nodejs
的开发中的核心内容。而大部分人在使用npm
时,主要使用她的包管理系统。node
可是,当咱们稍微look look那些知名的开源项目,或者老牛们的代码时,经常都能在它们的package.json
里看到一个写满了命令的scripts
属性。这里面都隐藏了哪些秘密,牛牛们都用它作了什么,怎么作到的?这些疑问一定撕扯着你的好奇心,来,咱们今天就聊聊神秘的scripts
属性。git
一般状况下,应用程序只能处理来自内部的消息,若是但愿对外部发来的消息也能拦截处理,那就须要一种叫钩子(Hook)的技术。想象一下,npm test
这个过程你是控制不了的,但若是就很是想在test
以前自动处理点什么事儿,怎么办?没次都手动在test
以前执行什么,烦不烦、烦不烦、烦不烦?就是不烦,也会忘啊!github
这时候就用到咱们的Hook了。下面这些指令都是Hook,它们均可以在package.json
的scripts
属性里定义,而且会在生命周期的某个指定时刻被执行,这就是上面提到的“对外部发来的消息也能拦截处理”,这极大的方便了开发人员(或许你想作点坏事儿?)npm
prepublish
: 在publish
该包以前执行。(在包目录下执行npm install
时也会执行)json
postpublish
: 在该包publish
以后执行post
preinstall
: 在该包被install
以前执行操作系统
postinstall
: 在该包被install
以后执行eslint
preuninstall
: 在该包被uninstall
以前执行rest
postuninstall
: 在该包被uninstall
以后执行code
preversion
: 在修改该包的version
以前执行
postversion
: 在修改该包的version
以后执行
pretest
, posttest
: 在该包内执行test
时执行,其中pretest
先于posttest
prestop
, poststop
: 在该包内执行stop
时执行,其中prestop
先于poststop
prestart
,poststart
: 在该包内执行start
时执行,其中prestart
先于poststart
prerestart
, postrestart
: 在该包内执行restart
脚本时执行,其中prerestart
先于postrestart
。注意: 若是没有在scripts
里显示指定restart
脚本,则会自动调用stop
,而后再start
上面这些Hooks都是npm
预约义好的,也就是说,当你执行npm install
时,若是你在scripts
里定义了preinstall
和postinstall
,那它们分别会在npm install
以前/后自动执行,不劳你操心!碉堡了,有木有?
还有,任何自定义脚本(经过npm run-script <脚本名>
来执行)也能够前缀pre
和post
为其制做钩子。好比:premyscript
,myscript
,postmyscript
注:也可使用
run
做为run-script
的简写使用。
若是你写了一个类库,有些操做和操做系统无关,但却但愿在该包被使用前执行,能够试试prepublish
,意思是,在你执行npm publish
的时候,自动先执行scripts
里定义的prepublish
里的脚本。
举个栗子:假设我用CoffeeScript
写了一个类库,我有下面两个愿望:
我但愿发布的是JavaScript
版本,这样用户npm install <类库>
以后无需搭建神马乱七八糟的环境,便可直接使用
我但愿发布的是一个minified版本,即用户npm install <类库>
以后,也可直接引入使用,而没必要关心还要帮我压缩一次
OK,咱们如今来聊聊这里我用prepublish
的好处:
这事儿执行一次就够,就是我publish
包的时候,不须要神马用户每次install
的时候也作
coffee-script
能够做为devDependencies
在个人项目里,这样的话,用户在install
这个类库的时候,就不会下载coffee-script
了。
uglify-js
也能够做为devDependencies
在个人项目里,好处同上
再好比,写了一个类库,其中有些操做是和操做系统相关的,可使用postinstall
看看。
那我以前写的一个movoto-cli举例,我有一个指望:
用户在install
个人类库后,这个类库要将两个配置文件eslintrc_browser_legacy.json
和eslintrc_node.json
里的LINEBREAK_OS
字段根据用户的操做系统修改成正确的值。
因而我把这个操做写在了postinstall
这个Hook里,问题解决,完美,没问题!
常常听到有朋友问到这样的问题,说看到有人的scripts
里写了"test": "mocha --reporter nyan"
,以为这个代码有漏洞,使用这个指令的人,必须得先npm install -g mocha
(全局安装mocha
),不然test
命令找不到mocha
,会报错的吧!
答案是这样的,通常这么写scripts
的,一般会把mocha
装在devDependencies
或者dependencies
里。scripts
里的指令有这样一个特色,若是你的类库(或叫模块)依赖的其它模块提供了可执行脚本(譬如:mocha
),那这些依赖会在你执行scripts
指令时自动被注入到执行进程的PATH
里。
这就是说,若是devDependencies
或者dependencies
里有mocha
,那在npm test
的时候,里面的mocha
命令,是从注入的PATH
里(即:node_modules/.bin/mocha
)找了。
So,还须要全局安装mocha
么?恐怕不须要了^^