npm scripts 官方文档(译)

本文翻译自npm官方script文档javascript

npm 支持运行package.json里“scripts”属性中的脚本,包括:java

  • prepublish:在npm publish命令以前运行(也会在不带参数的npm install命令前运行,详情在下段描述)node

  • prepare: 在两种状况前运行,一是npm publish命令前,二是不带参数的npm install命令;它会在prepublish以后、prepublishOnly以前执行git

  • prepublishOnly: 在npm publish命令前执行github

  • publish,postpublish: 在npm publish命令后执行npm

  • preinstall: 在npm install命令前执行json

  • install,postinstall: 在npm install命令后执行curl

  • preuninstall,uninstall: 在npm uninstall命令前执行工具

  • postuninstall : 在npm uninstall命令后执行post

  • preversion:在改变包的version前执行

  • version: 在改变包的version后,但提交以前执行

  • postversion: 在提交version变动后执行

  • pretest, test, posttest: 伴随npm test命令

  • prestop, stop, poststop: 伴随npm stop命令

  • restart, start, poststart: 伴随 npm start命令

  • pre restart, restart, poststart: 伴随 npm restart命令。提示:假如scripts里没有写restart命令,npm默认会运行start、stop

  • preshrinkwrap, shrinkwrap, postshrinkwrap: 伴随 npm shrinkwrap 命令(用于固定依赖包版本)

另外,全部的script均可以用 npm run-script <stage>命令执行, pre 和 post 会自动匹配对应的script(例如 premyscript,my script, postmyscript),依赖包中的script能够用npm explore <pkg> -- npm run <stage> 来执行

prepublish 和 prepare

废弃告示:

从npm@1.1.71开始,npm CLI 会在npm publishnpm install以前执行prepubish脚本,由于这作法便于准备package环境(几种用法如本段下面描述)。但事实证实这让人很是困惑。因此在npm@4.0.0后,新增来一种事件prepare来替代上述功能。另一种新事件prepublishOnly做为替代策略,让用户避免以往npm版本的混乱行为。prepublishOnly 只在npm publish前执行(例如,publish前最后执行一次测试,以确保无误)

重要提示:在npm5中, prepublish只在npm publish前执行,即取代prepublishOnly,因此npm6即之后的版本会放弃prepublishOnly。到时就忘了这些矬事吧。

https://github.com/npm/npm/issues/10074 ,这里对此变动有过漫长的争论可做参考。

用法:

若是你须要在使用package以前执行某些操做,而不依赖于目标系统的操做系统或目录结构,请使用prepublish脚本。例如如下任务:

  • 把coffeescript源码编译成JS

  • 压缩js源码

  • 获取你的package所需的远程资源

在publish时作这些事情的好处是,它们能够在同一处完成,从而下降复杂性和差别性。另外,这意味着:

  • 你能够依赖于coffee-script做为devDependency,但你的用户不须要安装它。

  • 你不须要在包中包含min版本,以节省空间

  • 你的用户的电脑上没必要具备curl或wget或其余系统工具

预设脚本

npm 预设了几个script内容:

"start": "node server.js"

若是你的package根目录中有server.js, npm会默认以之做为start命令执行。

"install": "node-gyp rebuild"

若是你的package根目录下中有binding.gyp而你又没定义 install或preinstall脚本,npm会默认以npm-gyp编译。

用户

若是使用root权限调用npm,那么它会将uid更改成用户配置指定的uid,默认为nobody。设置unsafe-perm以使用root权限运行脚本。

环境

npm 脚本运行在 npm的设置和进程的当前状态 的环境中。(不知道怎么翻)
Package scripts run in an environment where many pieces of information are made available regarding the setup of npm and the current state of the process.

路径

若是你依赖的模块(如测试模块)定义了可执行脚本,那么这些可执行文件将被添加到PATH中执行。因此,若是你的package.json有这样的依赖:

{ 
  "name" : "foo", 
  "dependencies" : { "bar" : "0.1.x" }, 
  "scripts": { "start" : "bar ./test" } 
}

那么在你npm install时,bar会导进node_modules/.bin目录中,你能够运行npm start执行 bar脚本。

package.json变量

package.json的属性名会拼接上npm_package_前缀。例如若是你的package.json文件中有{“name”:“foo”,“version”:“1.2.5”}),那么你的脚本中npm_package_name会是foo,而npm_package_version会是1.2.5

配置

使用npm_config_前缀将配置参数放在环境中。例如你能够经过检查npm_config_root环境变量来查看目前生效的root配置。

特殊:package.json中的config对象

若是npm config中存在<name> [@ <version>]:<key>的配置参数,则package.json里config对应的key将在环境中被覆盖。例如,若是package.json中:

{ 
  "name" : "foo", 
  "config" : { "port" : "8080" }, 
  "scripts" : { 
    "start" : "node server.js" 
  } 
}

而server.js中这么写:

http.createServer(...).listen(process.env.npm_package_config_port)

那么用户能够这样覆写port变量:

npm config set foo:port 80

当前的生命周期事件

最后,npm_lifecycle_event环境变量表明当前执行循环的哪一个阶段。因此,你可使用单个脚本用于根据当前正在发生的事件切换的进程的不一样部分。

对象按照层级如下划线链接,若是您的package.json中有

{“scripts”:{“install”:“foo.js”}}

则能够在脚本中看到:

process.env.npm_package_scripts_install === "foo.js"

例子

假如你的package.json有以下设置:

{ "scripts" :
  { 
    "install" : "scripts/install.js", 
    "postinstall" : "scripts/install.js", 
    "uninstall" : "scripts/uninstall.js"
  }
}

那么在生命周期的installpostinstall阶段将调用scripts/install.js,在uninstall时将会调用scripts/uninstall.js
因为scripts/install.js在两个不一样的阶段都有运行,所以在这种状况下,查看npm_lifecycle_event变量是聪明的作法。

若是你想要运行make命令也没问题,这样写:

{ "scripts" :
  { 
    "preinstall" : "./configure", 
    "install" : "make && make install", 
    "test" : "make test"
  }
}

退出脚本

npm脚本是经过将该行做为脚本参数传给sh来运行的。

若是脚本不是以退出码0退出,则会停止该进程。

请注意,这些脚本文件没必要是nodejs甚至是javascript程序。他们只须要一些可执行文件。

钩子脚本

若是要为全部package在某生命周期事件中运行某脚本,则可使用钩子脚本。

node_modules/.hooks/{eventname}中放置一个可执行文件,全部装在根目录下的package在运行到该生命周期节点时都会执行。

Hook脚本的运行方式与package.json里的脚本彻底相同。也就是说,它们与上述env在一个单独的子进程中。

实践建议

  • 不要以0之外的错误码退出,除非你真的想这样作。由于这将致使npm操做失败(install脚本除外),并可能会回滚。若是这个错误可有可无或只会阻断一些小功能,那么最好只是输出一个警告,让线程成功退出。

  • 尽可能不要使用npm脚原本作npm自己就能够作的事情。通读package.json文件,你能够学到全部经过简单、合适的配置来具体描述你的package。这一般更健壮和通用。

  • 经过检查env来决定把东西装在哪。例如,若是npm_config_binroot环境变量设置为/home/user/bin,那么不要尝试将可执行文件安装到/usr/local/bin中。用户可能由于某种缘由设置了这种方式。

  • 不要在脚本命令里加sudo前缀。若是因为某些缘由须要root权限,不然会报错;那么用户应该考虑以sudo运行npm命令。

  • 不要使用install脚本。使用.gyp文件进行编译,其余状况则使用prepublish。你最好永远不要自定义preinstallinstall脚本。若是你要这样作,请优先考虑是否有其余办法。installpreinstall脚本的惟一正确使用场景是用做设置那些编译的目标目录。

相关文章
相关标签/搜索