nodejs/node と denoland/deno_std/node のアーキテクチャ
English version: Architecture of nodejs/node and denoland/deno_std/node - 経験は何よりも饒舌
この記事は Advent Calendar 2021 Deno の16日目です。
趣味でdenoland/deno_stdにコントリビュートしており、特に denoland/deno_std/node をよく見ているので、nodejs/node と denoland/deno_std/node の現時点(2021/12/16)でのNode APIにまつわるアーキテクチャの違いをざっくり書いていこうと思います。
APIの実装場所
nodejs/node
node/libに実装されています。
Query stringを例にすると、node/lib/querystring.jsでロジックが実装されていて、ここでexportされています。
また、exportする必要のない内部のコードがnode/lib/internalで実装されています。
Query stringではencordStrなどの関数がexportされて、node/lib/querystring.js
でimportされています。
denoland/deno_std
deno_std/nodeに実装されています。
deno_std/node/querystirng.tsでnodejs/node/lib/querystring.js
でexportされているロジックと互換性のあるAPIがここでexportされています。
また、deno_std/node/internalで、nodejs/node/lib/internal
相当の実装がされています。
Implementation Language
nodejs/node
JavaScriptとC++で実装されています。
URLを例にすると、node/lib/url.js
やnode/lib/internal/url.js
といったJavaScriptの実装の中で一部、internalBindingによってC++のコードが呼び出されています。
例えばdomainToASCIIの実装はnode/src/node_url.ccにされています。
ちなみに、なぜJavaScriptで実装されていないのかと疑問を持ち、helpレポジトリでWhy domainToASCII is written by C++ not JS?と伺ったところ、for perf reasonsという回答をいただきました。
また、各所でprimordialsが使われています。
primordialsについてはプロトタイプ汚染周りの提案と primordials.jsが詳しいです。
denoland/deno_std
JavaScriptとTypeScriptで実装されています。
例えばQuery stringはquerystring.ts
で実装されていますが、Bufferはnode/_buffer.jsで実装されており、node/buffer.tsで@deno-types
にnode/_buffer.d.tsが指定されています。
NodeのinternalBindingに相当する実装はnode/internal_bindingでTypeScriptにより実装されています。
primordialsは、denoland/denoには導入されていますが、denoland/deno_stdには導入されていません。
テスト
nodejs/node
node/testにあります。
例えばURLのテストはnode/test/parallel/test-url-*.js
で実装されています。
実行方法などはpull-requests.mdにまとまっています。
denoland/deno_std
node/_tools/config.jsonで、nodejs/node/test
にあるテストのファイル名を指定し、node/_tools/setup.tsで取得し、node/_tools/suitesに配置しています。
実行方法などはnode/README.mdにまとまっています。