npm-hooks

众所周知,npm是工程师们基于nodejs的开发中的核心内容。而大部分人在使用npm时,主要使用她的包管理系统。node

可是,当咱们稍微look look那些知名的开源项目,或者老牛们的代码时,经常都能在它们的package.json里看到一个写满了命令的scripts属性。这里面都隐藏了哪些秘密,牛牛们都用它作了什么,怎么作到的?这些疑问一定撕扯着你的好奇心,来,咱们今天就聊聊神秘的scripts属性。git

Hooks(钩子)

一般状况下,应用程序只能处理来自内部的消息,若是但愿对外部发来的消息也能拦截处理,那就须要一种叫钩子(Hook)的技术。想象一下,npm test这个过程你是控制不了的,但若是就很是想在test以前自动处理点什么事儿,怎么办?没次都手动在test以前执行什么,烦不烦、烦不烦、烦不烦?就是不烦,也会忘啊!github

这时候就用到咱们的Hook了。下面这些指令都是Hook,它们均可以在package.jsonscripts属性里定义,而且会在生命周期的某个指定时刻被执行,这就是上面提到的“对外部发来的消息也能拦截处理”,这极大的方便了开发人员(或许你想作点坏事儿?)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里定义了preinstallpostinstall,那它们分别会在npm install以前/后自动执行,不劳你操心!碉堡了,有木有?

还有,任何自定义脚本(经过npm run-script <脚本名>来执行)也能够前缀prepost为其制做钩子。好比:premyscriptmyscriptpostmyscript

注:也可使用run做为run-script的简写使用。

说说常见的使用场景1

若是你写了一个类库,有些操做和操做系统无关,但却但愿在该包被使用前执行,能够试试prepublish,意思是,在你执行npm publish的时候,自动先执行scripts里定义的prepublish里的脚本。

举个栗子:假设我用CoffeeScript写了一个类库,我有下面两个愿望:

  1. 我但愿发布的是JavaScript版本,这样用户npm install <类库>以后无需搭建神马乱七八糟的环境,便可直接使用

  2. 我但愿发布的是一个minified版本,即用户npm install <类库>以后,也可直接引入使用,而没必要关心还要帮我压缩一次

OK,咱们如今来聊聊这里我用prepublish的好处:

  1. 这事儿执行一次就够,就是我publish包的时候,不须要神马用户每次install的时候也作

  2. coffee-script能够做为devDependencies在个人项目里,这样的话,用户在install这个类库的时候,就不会下载coffee-script了。

  3. uglify-js也能够做为devDependencies在个人项目里,好处同上

说说常见的使用场景2

再好比,写了一个类库,其中有些操做是和操做系统相关的,可使用postinstall看看。

那我以前写的一个movoto-cli举例,我有一个指望:
用户在install个人类库后,这个类库要将两个配置文件eslintrc_browser_legacy.jsoneslintrc_node.json里的LINEBREAK_OS字段根据用户的操做系统修改成正确的值。

因而我把这个操做写在了postinstall这个Hook里,问题解决,完美,没问题!

Environment

常常听到有朋友问到这样的问题,说看到有人的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么?恐怕不须要了^^

本站公众号
   欢迎关注本站公众号,获取更多信息