- JDK 23 対応 GraalVM (最新)
- JDK 24 対応 GraalVM (早期アクセス)
- JDK 21 対応 GraalVM
- JDK 17 対応 GraalVM
- アーカイブ
- 開発ビルド
Node.js ランタイム
GraalVM は、変更されていない Node.js アプリケーションを実行できます。 GraalVM の Node.js ランタイムは、最新バージョンの Node.js に基づいており、Google V8 の代わりに GraalVM JavaScript エンジン (GraalJS) を実行します。一部の内部機能 (VM 内部統計、構成、プロファイリング、デバッグなど) はサポートされていないか、動作が異なる可能性があります。
アプリケーションは、ネイティブなものも含め、NPM パッケージを自由にインポートして使用できます。
Node.js を使い始める #
JDK 21 用の GraalVM 以降、GraalVM Node.js ランタイムは個別のディストリビューションとして利用できます。 Oracle GraalVM と GraalVM Community Edition の両方で、2 つのスタンドアロン ランタイム オプションが利用可能です。ネイティブ イメージでコンパイルされたランチャーまたは 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.js 機能は、アプリケーションが `node` バイナリ ランチャーから起動されたときに使用できます。 Java コンテキストから Node.js アプリケーションを起動したり、NPM パッケージにアクセスしたりする場合には、特定の制限が適用されます。 Node.js vs. Java スクリプト コンテキスト を参照してください。
`npm` を使用したパッケージのインストール #
Node.js パッケージをインストールするには、`npm` ランチャーを使用します。 `npm` コマンドはデフォルトの NPM コマンドと同等であり、そのほとんどのオプションをサポートしています。
NPM パッケージは、次のようにインストールできます
npm install [package]
GraalVM Node.js の `npm` コマンドは NPM とほぼ互換性があるため、パッケージは想定どおり *node_modules/* ディレクトリにインストールされます。
`npm` パッケージをグローバルにインストールする #
Node パッケージは、`npm` と `-g` オプションを使用してグローバルにインストールできます。 デフォルトでは、`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 では、ワーカー スレッドを作成して JavaScript コードを並列実行できますが、JavaScript オブジェクトはワーカー間で共有できません。 逆に、GraalVM Java 相互運用性を使用して作成された Java オブジェクト (たとえば、`Java.type()` を使用) は、Node.js ワーカー間で共有できます。 これにより、マルチスレッド Node.js アプリケーションは Java オブジェクトを共有できます。
GraalVM Node.js ユニット テスト には、マルチスレッド Node.js アプリケーションの例がいくつか含まれています。 最も注目すべき例は、次の方法を示しています
- Node.js ワーカースレッドは Java コードを実行できます.
- Java オブジェクトは Node.js ワーカースレッド間で共有できます.
- JavaScript `Promise` オブジェクトを使用して、ワーカーからのメッセージを `await` し、Java オブジェクトを使用して promise をワーカー メッセージにバインドできます.
よくある質問 #
GraalVM の Node.js ランタイムは、元の Node 実装と互換性がありますか? #
GraalVM の Node.js ランタイムは、元の Node.js (V8 エンジンに基づく) とほぼ互換性があります。 これにより、多数の `npm` ベースのモジュールが互換性を持つようになります。 実際、テストした 100k の `npm` モジュールのうち、94% 以上がすべてのテストに合格しています。それでも、いくつかの違いのソースを考慮する必要があります
-
**セットアップ:** GraalVM の Node.js は、`node` 実行可能ファイル、`npm` などを含む、元の Node のセットアップをほとんど模倣しています。 ただし、すべてのコマンドライン オプションがサポートされているわけではありません (またはまったく同じように動作するわけではありません)。 モジュールでは、ネイティブ モジュールが *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 テスト フレームワークを使用する 95k モジュールに対してテストされます。 mocha を使用すると、テストを実行し、テスト結果を理解するプロセスを自動化できます。
- 一般的なモジュールの手動テスト: 選択された `npm` モジュール リストは、手動テスト セットアップでテストされます。 これらの非常に関連性の高いモジュールは、より高度な方法でテストされます。
NPM パッケージをグローバルにインストールできますか? #
Node パッケージは、GraalVM の Node.js 実装の両方で、`npm` と `-g` オプションを使用してグローバルにインストールできます。
元の Node.js 実装には、バイナリとグローバルにインストールされたパッケージとそのコマンドライン ツールを配置するためのメイン ディレクトリ (*node/bin/*) が 1 つありますが、GraalVM の Node.js はバイナリを */path/to/graaljs/bin/* ディレクトリに配置します。 GraalVM Node.js ランタイムに NPM パッケージをグローバルにインストールする場合、コマンド ライン インターフェース ツールなどの実行可能ファイルへのリンクは、JavaScript 固有のディレクトリに配置されます。 グローバルにインストールされたパッケージが正しく機能するためには、*/path/to/graaljs/bin* を `$PATH` に追加する必要がある場合があります。
別のオプションは、`$PREFIX` 環境変数を設定するか、`npm install` を実行するときに `--prefix` オプションを指定することにより、`npm` のグローバル インストール ディレクトリを指定することです。
詳細については、`npm` パッケージをグローバルにインストールする を参照してください。