本文档说明如何在基于 Node 模块的 Homebrew 公式中成功使用 Node 和 npm。
npm install
Homebrew 在 Language::Node
模块中提供了两个帮助器方法:std_npm_install_args
和 local_npm_install_args
。它们都为 npm 设置了正确的环境,并为 npm install
返回了针对其特定用例的参数。你的公式应使用这些方法,而不是显式调用 npm install
。标准 Node 模块安装的语法为
system "npm", "install", *Language::Node.std_npm_install_args(libexec)
其中 libexec
是目标前缀(通常是 libexec
变量)。
如果 Node 模块也在 npm 注册表中可用,我们更喜欢 npm 托管的发布 tarball,而不是 GitHub(或其他地方)托管的源 tarball。这些 tarball 的优点在于,它们不包含 .npmignore
中的文件(例如测试),从而减小了下载大小,并且任何可能的转换步骤都已经完成(例如,无需将 CoffeeScript 文件编译为构建步骤)。
npm 注册表 URL 通常具有以下格式
https://registry.npmjs.org/<name>/-/<name>-<version>.tgz
或者,你可以在 https://registry.npmjs.org/<name>
上 curl
JSON,并查找 versions[<version>].dist.tarball
的值以获取正确的 tarball URL。
与最新 Node 版本兼容的 Node 模块应声明对 node
公式的依赖项。
depends_on "node"
如果你的公式需要使用较旧的 Node 版本执行,则应使用其一个版本化公式(例如 node@12
)。
如果你的 Node 模块是原生插件或其依赖项树中的某个位置有原生插件,则必须声明一个附加依赖项。由于原生插件的编译会导致调用 node-gyp
,因此我们需要对 "python"
有一个额外的构建时间依赖项(因为 GYP 依赖于 Python)。
depends_on "python" => :build
另请注意,此类公式仅与最初编译时相同的 Node 主要版本兼容。这意味着我们需要在 node
公式的每次主要版本升级时,修改每个带有 Node 原生插件的公式。为了确保我们不会在 Node 主要版本升级时忽略你的公式,请编写一个有意义的测试,该测试在这种情况下会失败(使用 ABI 不兼容的 Node 版本调用)。
Node 模块应安装到 libexec
。这可以防止 Node 模块污染全局 node_modules
,这一点很重要,这样 npm 才不会尝试管理 Homebrew 安装的 Node 模块。
在下面,我们区分使用公式安装的两种类型的 Node 模块
std_npm_install_args
(如 apollo-cli
或 webpack
)npm install
调用不是唯一必需的安装步骤(例如,还需要编译非 JavaScript 源)的公式,必须使用 local_npm_install_args
(如 emscripten
或 grunt-cli
)这两种方法的共同点是,它们为在 Homebrew 中使用 npm 设置了正确的环境,并返回了为其特定用例调用 npm install
的参数。这包括通过在 HOMEBREW_CACHE
中使用我们自己的自定义 npm_cache
来修复 npm 缓存的一个重要边缘情况(由 Homebrew 在构建和测试过程中重定向 HOME
引起),否则会导致非常长的构建时间和较高的磁盘空间使用率。
要使用它们,您必须在公式文件的开头使用以下命令请求 Node 语言模块
require "language/node"
std_npm_install_args
将全局样式模块安装到 libexec
在公式的 install
方法中,只需在必要时 cd
到 Node 模块的顶级目录,然后使用 system
调用 npm install
,并使用 Language::Node.std_npm_install_args
,如下所示
system "npm", "install", *Language::Node.std_npm_install_args(libexec)
这会将您的 Node 模块安装到 npm 的全局模块样式中,并使用自定义前缀 libexec
。所有模块的可执行文件都将由 npm 自动解析到 libexec/bin
中,这些文件不会符号链接到 Homebrew 的前缀中。为了确保安装这些文件,我们需要使用以下命令将所有可执行文件符号链接到 bin
bin.install_symlink Dir["#{libexec}/bin/*"]
local_npm_install_args
本地安装模块依赖项在公式的 install
方法中,执行在 npm install
步骤之前需要完成的所有安装步骤,然后 cd
到包含的 Node 模块的顶级目录。然后,使用 system
调用 npm install
,并使用 Language::Node.local_npm_install_args
,如下所示
system "npm", "install", *Language::Node.local_npm_install_args
这会将所有 Node 模块的依赖项安装到您的本地构建路径。您现在可以继续执行构建步骤,并按照 通用 Homebrew 公式说明 自行处理安装到 Homebrew 前缀中的操作。
安装基于标准 Node 模块的公式如下所示
require "language/node"
class Foo < Formula
desc "An example formula"
homepage "https://example.com"
url "https://registry.npmjs.org/foo/-/foo-1.4.2.tgz"
sha256 "abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1"
depends_on "node"
# uncomment if there is a native addon inside the dependency tree
# depends_on "python" => :build
def install
system "npm", "install", *Language::Node.std_npm_install_args(libexec)
bin.install_symlink Dir["#{libexec}/bin/*"]
end
test do
# add a meaningful test here, version isn't usually meaningful
assert_match version.to_s, shell_output("#{bin}/foo --version")
end
end
您可以使用 homebrew-npm-noob 为 npm 软件包自动生成如上示例所示的公式。