生命周期脚本
包可以在清单的 scripts
字段中定义各种操作,当包管理器执行特定工作流时应执行这些操作。
请注意,我们不支持 npm 中最初存在的每个生命周期脚本。这是一个经过深思熟虑的决定,基于这样的观察:过多的生命周期脚本会让人难以知道在什么情况下使用哪一个,从而导致混乱和错误。如果提供了令人信服的用例,我们愿意逐案添加缺少的脚本。
特别是,我们有意不支持用户定义脚本的任意 pre
和 post
钩子(例如 prestart
)。此行为导致脚本变为隐式而不是显式,混淆了执行流程。它有时还会导致令人惊讶的行为,例如 yarn serve
也运行 yarn preserve
。
prepack
和 postpack
这些脚本在每次调用 yarn pack
的开始和结束时调用。它们分别用于将你的包从开发状态变为生产状态,并清理任何残留的工件。例如,一个典型的 prepack
脚本将在源目录上调用 Babel 或 TypeScript,将 .ts
文件转换为 .js
文件。
prepublish
此脚本在 yarn npm publish
之前调用,甚至在打包包之前调用。这是您需要检查项目是否处于正常状态的位置。
由于它仅在预发布时调用,预发布挂钩不应产生副作用。特别是不要在 prepublish
中转换包源,因为直接使用存储库(例如通过 git:
协议)的人将无法使用您的项目。相反,请使用 prepack
。
postinstall
此脚本在包依赖项树以任何方式更改后调用——通常在添加、删除或更新依赖项(或传递依赖项)后调用,但也可能在项目配置或环境更改时调用(例如在更改 Node.js 版本时)。
保证按拓扑顺序调用(换句话说,您的依赖项的 postinstall
脚本将始终在您的脚本之前运行)。
为了向后兼容,如果存在 preinstall
和 install
脚本,它们将在运行同一包的 postinstall
脚本之前立即调用。一般来说,优先使用 postinstall
而非这两个脚本。
应不惜一切代价避免使用 postinstall 脚本,因为它们会使安装变得更慢、更有风险。许多用户会拒绝安装具有 postinstall
脚本的依赖项。此外,由于输出不会开箱即用地显示,因此使用它们向用户打印消息不会按预期工作。
环境变量
在运行脚本和二进制文件时,通常会提供一些环境变量
变量 | 说明 |
---|---|
$INIT_CWD | 调用脚本的目录。这与 cwd 不同,对于脚本,cwd 始终等于最近的包根目录。 |
$PROJECT_CWD | 项目在文件系统上的根目录。 |
$npm_package_name | 正在运行的包的名称。 |
$npm_package_version | 正在运行的包的版本。 |
$npm_package_json | 正在运行的包的 package.json 的绝对路径。 |
$npm_execpath | Yarn 二进制文件的绝对路径。 |
$npm_node_execpath | Node 二进制文件的绝对路径。 |
$npm_config_user_agent | 定义当前正在使用的 Yarn 版本的字符串。 |
$npm_lifecycle_event | 脚本或生命周期事件的名称(如果相关)。 |