NPM-脚本
NPM-脚本
npm如何处理“脚本”字段
描述
对于以下脚本,npm 支持 package.json 文件的“scripts”属性:
prepublish
:在包打包和发布之前运行,以及在npm install
没有任何参数的本地运行。(见下文)
此外,可以通过运行执行任意脚本npm run-script <stage>。前置和后名称匹配的命令将这些运行以及(例如premyscript,myscript, postmyscript)。可以运行依赖项的脚本npm explore <pkg> -- npm run <stage>。
预先准备和准备
弃权说明
因为npm@1.1.71
,CLI 已运行prepublish
两个脚本npm publish
和npm install
,因为它是准备使用的包装(一些常见的用例在下面的章节中描述)的简便方法。事实上,它在实践中也非常令人困惑。截至npm@4.0.0
目前,已经引入了一个新事件prepare
,它保留了现有的行为。一个 新的事件,prepublishOnly
已作为一个过渡性的策略,让用户避免现有 NPM版本的混乱行为,并只运行npm publish
(例如,运行测试的最后一次,以确保他们在良好的状态)。
有关此更改,请参阅https://github.com/npm/npm/issues/10074以获得更长的理由,并进一步阅读。
用例
如果需要在使用包之前对包执行操作,请以不依赖于操作系统或目标系统体系结构的方式使用prepublish
脚本。这包括以下任务:
- 将 CoffeeScript 源代码编译为 JavaScript 。
这些事情的优势prepublish
在于它们可以在一个地方完成一次,从而降低了复杂性和可变性。此外,这意味着:
- 你可以依靠
coffee-script
的devDependency
,因此用户并不需要把它安装。
默认值
npm 将根据包内容默认一些脚本值。
"start": "node server.js"
: 如果server.js
包的根目录中有文件,那么npm将默认start
命令为node server.js
。
用户
如果使用 root 权限调用 npm,则它会将 uid 更改为user
配置指定的用户帐户或 uid ,默认为nobody
。设置unsafe-perm
标志以使用 root 权限运行脚本。
环境
包脚本在一个环境中运行,在该环境中提供有关 npm 设置和进程当前状态的许多信息。
路径
如果依赖于定义可执行脚本的模块(如测试套件),那么这些可执行文件将添加到PATH
执行脚本中。所以,如果你的 package.json 有这个:
{ "name" : "foo"
, "dependencies" : { "bar" : "0.1.x" }
, "scripts": { "start" : "bar ./test" } }
然后你可以运行npm start
来执行bar
脚本,该脚本被导出到node_modules/.bin
目录中npm install
。
package.json vars
package.json字段被添加到npm_package_
前缀上。因此,例如,如果您{"name":"foo", "version":"1.2.5"}
在 package.json 文件中,那么您的包脚本将 npm_package_name
环境变量设置为“foo”,并将 npm_package_version
设置设置为“1.2.5”。您可以使用process.env.npm_package_name
和 在代码中访问这些变量process.env.npm_package_version
,依此类推其他字段。
组态
配置参数放在带有npm_config_
前缀的环境中 。例如,您可以root
通过检查npm_config_root
环境变量来查看有效配置。
特殊:package.json“config”对象
如果存在 config 参数,则在环境中覆盖 package.json“config ”键<name>[@<version>]:<key>。例如,如果 package.json 具有:
{ "name" : "foo"
, "config" : { "port" : "8080" }
, "scripts" : { "start" : "node server.js" } }
和 server.js 是这样的:
http.createServer(...).listen(process.env.npm_package_config_port)
然后用户可以通过执行以下操作来更改行为:
npm config set foo:port 80
当前的生命周期事件
最后,npm_lifecycle_event
环境变量设置为正在执行循环的任何阶段。因此,您可以使用单个脚本来处理流程的不同部分,这些部分根据当前发生的情况进行切换。
按照这种格式对象被展平,所以如果你 {"scripts":{"install":"foo.js"}}
在package.json 中,那么你会在脚本中看到这个:
process.env.npm_package_scripts_install === "foo.js"
例子
例如,如果 package.json 包含以下内容:
{ "scripts" :
{ "install" : "scripts/install.js"
, "postinstall" : "scripts/install.js"
, "uninstall" : "scripts/uninstall.js"
}
}
然后scripts/install.js
将调用生命周期的安装和安装后阶段,并scripts/uninstall.js
在卸载软件包时调用。由于 scripts/install.js
运行了两个不同的阶段,因此在这种情况下查看npm_lifecycle_event
环境变量是明智的。
如果要运行 make 命令,可以执行此操作。这很好用:
{ "scripts" :
{ "preinstall" : "./configure"
, "install" : "make && make install"
, "test" : "make test"
}
}
EXITING
通过将行作为脚本参数传递给脚本来运行脚本sh
。
如果脚本以 0 以外的代码退出,则会中止该过程。
请注意,这些脚本文件不必是 nodejs 甚至是 javascript 程序。它们只需要是某种可执行文件。
HOOK SCRIPTS
如果要在特定生命周期事件中为所有包运行特定脚本,则可以使用钩子脚本。
将可执行文件放在node_modules/.hooks/{eventname}
,并且当它们在包生命周期中为该根中安装的任何软件包进行该点时,它将被运行。
Hook脚本的运行方式与 package.json 脚本完全相同。也就是说,它们处于一个单独的子进程中,具有上述的 env 。
最佳实践
- 除非您的意思是真的
,
否则不要使用非零错误代码退出。除卸载脚本外,
这将导致npm操作失败,
并可能会回滚。如果故障很小或只会阻止某些可选功能,
那么最好只打印警告并成功退出。