- 適用於 JDK 23 的 GraalVM (最新)
- 適用於 JDK 24 的 GraalVM (搶先體驗)
- 適用於 JDK 21 的 GraalVM
- 適用於 JDK 17 的 GraalVM
- 封存
- 開發建置
Node.js 執行期
GraalVM 可以執行未經修改的 Node.js 應用程式。GraalVM 的 Node.js 執行期基於最新版本的 Node.js,並執行 GraalVM JavaScript 引擎 (GraalJS) 而非 Google V8。某些內部功能 (例如,VM 內部統計資料、組態、效能分析、偵錯等) 不受支援,或支援時行為可能有所不同。
應用程式可以自由匯入和使用 NPM 套件,包括原生套件。
Node.js 入門 #
從適用於 JDK 21 的 GraalVM 開始,GraalVM Node.js 執行期可作為單獨的發行版本提供。Oracle GraalVM 和 GraalVM Community Edition 皆提供兩種獨立的執行期選項:Native Image 編譯的啟動器或基於 JVM 的執行期。為了區分它們,GraalVM Community Edition 版本在名稱中帶有後綴 -community
:graaljs-community-<version>-<os>-<arch>.tar.gz
、graalnodejs-community-<version>-<os>-<arch>.tar.gz
。隨附 JVM 的獨立版本在名稱中帶有 -jvm
後綴。
若要啟用 GraalVM Node.js 執行期,請安裝基於 Oracle GraalVM 或 GraalVM Community Edition 的 Node.js 發行版本,以適用於您的作業系統。
-
導覽至 GitHub 版本 並為您的作業系統選擇所需的獨立版本。
- 解壓縮封存
tar -xzf <archive>.tar.gz
或者,在 Finder 中開啟檔案。
- 檢查版本以查看執行期是否處於活動狀態
./path/to/bin/node --version
執行 Node.js 應用程式 #
Node.js 安裝提供 node
和 npm
啟動器
node [options] [filename] [args]
npm
命令等同於預設的 Node.js 命令,並具有額外的 GraalVM 特定功能 (例如,與 Java 的互通性)。可以使用 node --help
取得可用選項的清單。
使用 node
啟動器執行 Node.js 應用程式。例如
- 使用
npm install
安裝colors
和ansispan
套件,如下所示npm install colors ansispan
安裝套件後,您可以從應用程式中使用它們。
- 將以下程式碼片段新增至名為 app.js 的檔案,並將其儲存在您安裝 Node.js 套件的相同目錄中
const http = require("http"); const span = require("ansispan"); require("colors"); http.createServer(function (request, response) { response.writeHead(200, {"Content-Type": "text/html"}); response.end(span("Hello Node.js!".green)); }).listen(8000, function() { console.log("Node.js server running at http://127.0.0.1:8000/".red); }); setTimeout(function() { console.log("DONE!"); process.exit(); }, 2000);
- 使用
node
命令在 GraalVM Node.js 執行期上執行它,如下所示node app.js
當從 node
二進位啟動器啟動應用程式時,Node.js 功能可用。從 Java 內容啟動 Node.js 應用程式或存取 NPM 套件時,會有一些限制,請參閱 Node.js 與 Java Script Context。
使用 npm
安裝套件 #
若要安裝 Node.js 套件,請使用 npm
啟動器。npm
命令等同於預設的 NPM 命令,並支援其大多數選項。
可以使用以下方式安裝 NPM 套件
npm install [package]
由於 GraalVM Node.js 的 npm
命令與 NPM 大致相容,因此套件會如預期地安裝在 node_modules/ 目錄中。
全域安裝 npm
套件 #
可以使用 npm
和 -g
選項全域安裝 Node 套件。依預設,npm
會將全域套件 (連結到其可執行檔) 安裝在安裝 node
可執行檔的路徑中,通常是 node/bin/。該目錄是安裝全域套件的位置。如果您經常使用全域安裝的套件,尤其是它們的命令列介面,您可能會想要將該目錄新增至您的 $PATH
。
另一種選項是透過設定 $PREFIX
環境變數,或在執行 npm install
時指定 --prefix
選項,來指定 npm
的全域安裝目錄。例如,以下命令會將全域套件安裝在 /foo/bar/ 目錄中
npm install --prefix /foo/bar -g <package>
有關 prefix
的更多詳細資訊,可以在 官方 NPM 文件中找到。
與 Java 的互通性 #
Node.js 執行期無法嵌入到 JVM 中,但必須作為單獨的處理序啟動。
- 將以下程式碼儲存在名為 HelloPolyglot.java 的檔案中並進行編譯
import org.graalvm.polyglot.*; import org.graalvm.polyglot.proxy.*; public class HelloPolyglot { static String JS_CODE = "(function myFun(param){console.log('hello '+param);})"; public static void main(String[] args) { System.out.println("Hello Java!"); try (Context context = Context.create()) { Value value = context.eval("js", JS_CODE); value.execute(args[0]); } } }
- 然後將此程式碼儲存為名為 app.js 的檔案
var HelloPolyglot = Java.type("HelloPolyglot"); HelloPolyglot.main(["from node.js"]); console.log("done");
- 使用
node
執行它node --vm.cp=. app.js
您應該會看到以下輸出
Hello Java! hello from node.js done
然後,Node.js 和 JVM 皆會在相同的處理序中執行,並且互通性會使用與上述相同的 Value
類別運作。
若要了解執行 node
啟動器和從 Java Context
存取 Node.js NPM 模組或 ECMAScript 模組之間的差異,請參閱 NodeJSVSJavaScriptContext。
使用 Node.js 的多執行緒 #
GraalJS 的基本多執行緒模型也適用於 Node.js 應用程式。在 Node.js 中,可以建立 Worker 執行緒來並行執行 JavaScript 程式碼,但 JavaScript 物件無法在 Worker 之間共用。相反地,可以使用 GraalVM Java 互通性建立的 Java 物件 (例如,使用 Java.type()
) 可以在 Node.js Worker 之間共用。這允許多執行緒 Node.js 應用程式共用 Java 物件。
GraalVM Node.js 單元測試包含多執行緒 Node.js 應用程式的多個範例。最值得注意的範例顯示如何
- Node.js 工作執行緒可以執行 Java 程式碼.
- Java 物件可以在 Node.js 工作執行緒之間共用.
- 可以使用 JavaScript
Promise
物件來await
來自 Worker 的訊息,使用 Java 物件將 Promise 繫結到 Worker 訊息.
常見問題 #
GraalVM 的 Node.js 執行期與原始 Node 實作相容嗎? #
GraalVM 的 Node.js 執行期與原始 Node.js (基於 V8 引擎) 大致相容。這導致大量基於 npm
的模組相容。事實上,在我們測試的 10 萬個 npm
模組中,超過 94% 的模組通過了所有測試。儘管如此,仍必須考慮幾個差異來源
-
設定: GraalVM 的 Node.js 大部分模擬了 Node 的原始設定,包括
node
可執行檔、npm
和類似的內容。但是,並非所有命令列選項都受支援 (或行為完全相同)。模組可能需要針對 v8.h 檔案 (重新) 編譯原生模組。從適用於 JDK 21 的 GraalVM 開始,GraalVM Node.js 執行期可作為單獨的發行版本提供。請參閱Node.js 入門。
-
內部: GraalVM 的 Node.js 是在 JVM 之上實作的,因此具有與基於 V8 的 Node.js 不同的內部架構。這表示某些內部機制的行為有所不同,並且無法完全複製 V8 行為。這幾乎不會影響使用者程式碼,但可能會影響以原生方式實作的模組,這取決於 V8 內部機制。
-
效能: 由於 GraalVM 的 Node.js 是在 JVM 之上實作的,因此效能特性與原始原生實作有所不同。雖然 GraalVM 的尖峰效能在許多基準測試中可以與 V8 相匹配,但通常需要更長的時間才能達到尖峰 (稱為預熱)。在測量 (尖峰) 效能時,請務必給 Graal 編譯器一些額外的時間。
-
相容性: GraalVM 的 Node.js 執行期使用以下方法來檢查並保留與 Node.js 程式碼的相容性
- node-compat-table:GraalVM 的 Node.js 使用 node-compat-table 模組與其他引擎進行比較,突顯可能中斷 Node.js 程式碼的不相容性。
- 使用 mocha 自動進行大量模組測試:為了測試大量模組,GraalVM 的 Node.js 執行期會針對使用 mocha 測試框架的 9.5 萬個模組進行測試。使用 mocha 可以自動化執行測試並理解測試結果的過程。
- 人工測試熱門模組:在人工測試設定中測試了精選的
npm
模組清單。這些高度相關的模組會以更複雜的方式進行測試。
NPM 套件可以全域安裝嗎? #
可以使用 npm
和 -g
選項全域安裝 Node 套件,GraalVM 的 Node.js 實作也是如此。
雖然原始 Node.js 實作有一個主要目錄 (node/bin/) 來放置二進位檔案和全域安裝的套件及其命令列工具,但 GraalVM 的 Node.js 會將二進位檔案放在 /path/to/graaljs/bin/ 目錄中。在 GraalVM Node.js 執行期上全域安裝 NPM 套件時,可執行檔的連結 (例如,命令列介面工具的連結) 會放置到 JavaScript 特定目錄中。為了使全域安裝的套件正常運作,您可能需要將 /path/to/graaljs/bin
新增至您的 $PATH
。
另一個選項是透過設定 $PREFIX
環境變數,或在執行 npm install
時指定 --prefix
選項,來指定 npm
的全域安裝目錄。
如需更多詳細資訊,請參閱全域安裝 npm
套件。