公式作者的 Node

本文檔說明如何在基於 Node 模組的 Homebrew 公式中成功使用 Node 和 npm。

執行 npm install

Homebrew 在 Language::Node 模組中提供兩個輔助方法:std_npm_install_argslocal_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 登錄檔網址通常有下列格式

https://registry.npmjs.org/<name>/-/<name>-<version>.tgz

或者,您可以 curl https://registry.npmjs.org/<name> 中的 JSON,並尋找 versions[<version>].dist.tarball 的值,以取得正確的 tarball 網址。

相依性

與最新 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 模組類型

兩種方法的共通點是,它們會設定正確的環境,以便在 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 套件。

Fork me on GitHub