Skip to content

MS_NodeServices

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

Node Services

概要

  • ASP.NET Core から、Node.js のモジュールを呼び出すことができる。
  • Edge.js ってのもあるらしいが、メンテナンスが止まっている。

移行メモ(NodeServices 自体も廃止済み): 原文が
「Edge.js はメンテナンスが止まっている」と記録しているが、
Microsoft.AspNetCore.NodeServices も同じ道をたどった

【経緯】
   2017      NodeServices / SpaServices 登場
   2019-08   【廃止(Obsolete)が告知】(Issue #12890)
   .NET 3.0  [Obsolete] 属性が付き、警告が出る
   .NET 5    【パッケージの提供終了】★

詳細は JavaScript Services を参照。

詳細

...。

補足(何をしていたのか): 原文の詳細は空欄なので、
仕組みと、廃止の理由を補っておく。

// 当時の使い方
public class HomeController : Controller
{
    private readonly INodeServices _nodeServices;
    public HomeController(INodeServices nodeServices) => _nodeServices = nodeServices;

    public async Task<IActionResult> Index()
    {
        var result = await _nodeServices.InvokeAsync<string>("./scripts/render", "引数");
        return Content(result);
    }
}
// scripts/render.js(Node.js 側)
module.exports = function (callback, arg) {
    callback(null, `Hello from Node: ${arg}`);
};
【仕組み】
   ASP.NET Core プロセス
     └─ 【Node.js を子プロセスとして起動】
          └─ HTTP または名前付きパイプで通信
               └─ 指定した JS モジュールを実行し、結果を返す

廃止の理由:

問題 内容
プロセス管理が難しい 落ちた Node をどう再起動するか。ゾンビ プロセス
Node.js のバージョン管理 .NET 側の関心事になってしまう
デバッグが困難 どちらのプロセスで落ちたか分かりにくい
性能 プロセス間通信のオーバーヘッド。並行度の制御
配置 本番サーバに Node.js が要る。コンテナが太る
そもそも需要が薄かった 「.NET から npm を呼ぶ」場面が実は少ない

補足(「.NET から JavaScript を実行したい」への現在の答え): 要件を
分解してから手段を選ぶのが正しい。

【要件を問い直す】

 Q. なぜ Node.js の処理が必要なのか?
    ├ その npm パッケージにしかない機能がある
    │    → 【別サービスに切り出して HTTP で呼ぶ】★
    ├ サーバ サイド レンダリング(SSR)がしたい
    │    → 【Next.js / Nuxt / Angular Universal】(Node 側で完結)
    ├ ビルド時に webpack/Vite を動かしたい
    │    → 【ビルド時の話】。実行時に Node は要らない
    └ 単に JS を評価したい(式の評価、テンプレート)
         → 【Jint】(純 C# 製の JS インタープリター)
手段 内容 評価
別サービス + HTTP Node.js の Web API を立てる 最も素直。障害の分離もできる
Jint 純 C# 製の JS エンジン。Node.js 不要 軽量。Node の API は使えない
ClearScript V8 / ChakraCore を埋め込む 高速だがネイティブ依存
Process を自前で起動 node script.js を叩く NodeServices が内部でやっていたこと
Microsoft.JSInterop Blazor 内で JS を呼ぶ 用途が異なる(ブラウザ側)
// Jint の例(NuGet: Jint)
var engine = new Jint.Engine();
var result = engine.Evaluate("1 + 2 * 3").AsNumber();   // 7

Process を自前で起動する場合の注意:

・呼び出しごとに Node を起動すると【起動コストが支配的】(100ms 超)
   → 常駐させるなら、結局 NodeServices と同じ問題を抱える
・標準入出力の文字コード([エンコーディング] 参照)
・タイムアウトとプロセスの後始末を必ず実装する
・入力を引数に渡す場合、【コマンド インジェクションに注意】★

参考

Edge.js

Qiita

補足(Edge.js との違い): 名前が似た技術なので整理しておく。

NodeServices Edge.js
方向 .NET → Node.js 双方向(.NET ↔ Node.js)
構造 別プロセス(IPC) 同一プロセス(CLR を Node に埋め込む)
主体 Microsoft コミュニティ(Tomasz Janczuk)
現況 廃止 メンテナンス停止(原文の通り)
【Edge.js の構造】
   Node.js プロセスの中に【CLR をホストする】
     → プロセス間通信がない=速い
     → ただし【ネイティブ アドオンのビルドが必要】
       (node-gyp、Visual C++ ビルド ツール)
     → .NET のバージョンアップに追随できず、停止した

原文が「メンテナンスが止まっている」と 2018 年頃に記録した技術と、
それを紹介していた NodeServices の両方が、現在は使われていない
——
という結果になった。

教訓としては、JavaScript Services
補足と同じ
で、2 つのランタイムを 1 つのプロセス/プロジェクトに
押し込む方式は、長期的に維持が難しい
ということである。
境界はプロセス(あるいはサービス)で切る方が生き残る。

Microsoft Learn


Tags: 移行, プログラミング, .NET開発, .NET Core, ASP.NET, ASP.NET MVC

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally