Deno のディレクトリ構造 2024

この記事では、OSS の Deno プロジェクトのディレクトリ構造を解説します。(主に OSS の Deno にコントリビュートしたい人むけの記事です)

https://github.com/denoland/deno

```
deno/
├── bench_util/ (Deno のコアの仕組みのベンチマーク関連)
├── cli/ (Deno の CLI としての機能を実装する場所)
│   ├── args/ (コマンドラインフラグのパースをする場所)
│   ├── bench/ (各種ベンチマークスクリプト)
│   ├── cache/ (依存スクリプトのDLキャッシュや、ビルドしたスリプトのキャッシュ管理)
│   ├── js/ (テストと jupyter notebook 関連の JS API の実装)
│   ├── lsp/ (LSP の実装)
│   ├── npm/ (npm 互換関連の Rust の実装)
│   ├── ops/ (テストと jupyter notebook 関連の op の実装
│   ├── schemas/ (各種 json ファイル用の JSON Schema 置き場)
│   ├── standalone/ (deno compile 用の各種ユーティリティ)
│   ├── tools/ (サブコマンド類 (`deno lint`, `deno fmt`, etc) の実装)
│   ├── tsc/ (TypeScript 関連の実装、Deno の型の d.ts などの管理)
│   └── util/ (Rust の各種ユーティリティ)
├── ext/ (各 op の実装をカテゴリごとに分類したもの、各 ext モジュールは独立した crate になっている)
│   ├── broadcast_channel/ (BroadcastChannel 関連の op と JS の実装)
│   ├── cache/ (Cache API 関連の op の実装)
│   ├── canvas/ (Offscreen Canvas 関連の op と JS の実装)
│   ├── console/ (Console API 関連の op と JS の実装)
│   ├── cron/ (Deno KV Cron 関連の op と JS の実装)
│   ├── crypto/ (Web Crypto API 関連の op と JS の実装)
│   ├── fetch/ (Fetch API 関連の op と JS の実装)
│   ├── ffi/ (FFI 関連の op と JS の実装)
│   ├── fs/ (File system API 関連の op と JS の実装)
│   ├── http/ (http サーバー関連の op と JS の実装)
│   ├── io/ (I/O API の op と JS の実装)
│   ├── kv/ (Deno KV の op と JS の実装)
│   ├── napi/ (napi (Node API) の op と JS の実装)
│   ├── net/ (TCP/UDP/TLS API 関連の op と JS の実装)
│   ├── node/ (Node 互換機能の実装)
│   ├── tls/ (TLS 関連のユーティリティの実装)
│   ├── url/ (URL/URLPattern API 関連の op と JS の実装)
│   ├── web/ (各種 Web API 関連の op と JS の実装)
│   ├── webgpu/ (WebGPU 関連の op と JS の実装)
│   ├── webidl/ (WebIDL 関連の JS コードジェネレーションの実装)
│   ├── websocket/ (WebSocket API 関連の op と JS の実装)
│   └── webstorage/ (Web Storage 関連の op と JS の実装)
├── resolvers/ (モジュールリゾルバーの実装)
│   ├── deno/ (Deno 用リゾルバーの実装)
│   └── node/ (Node 用リゾルバーの実装)
├── runtime/
│   ├── examples/ (Deno を拡張した独自ランタイムを作るサンプル)
│   ├── ops/ (ext モジュールに分類されなかったその他の op の実装を置く場所)
│   └── js/ (ランタイムの JS 実装部分)
├── tests/ (インテグレーションテスト、JS のユニットテスト、Node 互換テストなどを含むディレクトリ)
│   ├── config/ (テスト用の各種コンフィグ置き場)
│   ├── ffi/ (FFI 機能のテスト)
│   ├── integration/ (Rust で記述されたインテグレーションテスト)
│   ├── napi/ (napi (Node API) 関連のテスト
│   ├── node_compat/ (Node.js のレポジトリからコピーしてきた Node.js の API のテストをする場所)
│   ├── registry/ (テスト用の npm レジストリ、JSR レジストリの fixture (テスト用パッケージ) 置き場)
│   ├── specs/ (spec テストという仕組みで書かれた、Deno コマンドを実行するタイプの結合テストを実装する場所)
│   ├── testdata/ (テスト用各種データ置き場)
│   ├── unit/ (Deno の JS API としてのユニットテスト置き場場所)
│   ├── unit_node/ (Deno の Node 互換レイヤーのユニットテスト置き場)
│   ├── util/ (テスト用各種ユーティリティ)
│   └── wpt/ (Web Platform Test の実装・設定)
├── third_party/ (開発に必要な外部依存ファイル置き場、git submodule になっていて中身は別管理されている)
└── tools/ (開発に必要な各種ユーティリティ置き場 (ex. フォーマッター、リンター)
```

以下では特に主要なディレクトリを解説します。

# `cli/`

Deno コマンドのエントリポイントや、各種ツール (fmt, lint) の実装を含むディレクトリ。ほぼ Rust で実装されている。JS ランタイムとしてのメイン部分は後述の `runtime/` 以下で実装されている。具体的な API は基本的には `ext/` 以下で実装されるが、テストランナー、ベンチマークランナー、ジュピターノートブック関連だけここに残ったままになっている。

# `ext/`

Deno namespace 以下の各種 API をカテゴリごとに分類して実装されている場所。例えば、ファイルシステム関連は `ext/fs`、HTTP サーバーは `ext/http` など。

各 ext モジュールは Rust で実装された op (JS から呼べる Rust の関数) と JS で実装した API 部分がセットになっている。各 ext は Rust crate 化されている。ext crate は本体に対してプラッガブルに付け外しが出来るようになっている。興味がない ext crate を外して軽量化した Deno を自分でカスタマイズして作ったりすることも出来る。また、自分で ext crate を書くことで Deno namespace を拡張した Deno をビルドしたりすることも出来るようになっている。

# `runtime/`

JS ランタイムとしてメインの実装がされている場所。大部分の具体的な API 関連の実装は前述の `ext/` モジュール以下にカテゴリ別に分類されているが、Web Worker API 関連、Permission API 関連など、いくつかの API はこのディレクトリ以下で実装されている。

`cli` ディレクトリと `runtime` ディレクトリは、JS ランタイムとしての挙動に必要なものは `runtime` 以下、それ以外は `cli` というように区別されている。

`deno compile` コマンドでは `denort` というバイナリファイル (JS runtime だけの状態の Deno) とユーザーのスクリプトを合成して実行ファイルを作るが、`denort` の内容は `runtime` ディレクトリの中の内容にほぼ一致する。

# `tests/`

Rust のユニットテスト以外の全てのテストが置かれている場所。

## `tests/unit`

Deno API / Web API のユニットテストを書く場所

## `tests/unit_node`

node 互換 API のユニットテストを書く場所。本来 node 互換 API は後述の `tests/node_compat` (Node.js レポジトリからコピーされたテスト) でテストされるべきだが、そちらでは何らかの不都合 (テストしたいことと粒度が合わないなど) があって独自にテストを書かないといけない場合にこちらにテストを書く。

## `tests/node_compat`

Node.js のレポジトリからコピーしてきたテストを設定・実行する場所。設定ファイル (`tests/node_compat/config.jsonc`) にどのテストをコピー・実行するかということが記述されているので、新たに node 互換 API を実装した場合はこの設定ファイルを編集して、新しいテストを有効化する。

## `tests/wpt`

[Web Platform Test](https://web-platform-tests.org/) を設定・実行する場所。設定ファイル (`tests/wpt/runner/expectation.json`) にどのファイル・テストケースが pass / fail するべきという事が記述されているので、新たに Web 互換 API を実装した場合はこの JSON ファイルを更新する。

## `tests/specs`

specs テストという独自の仕組みで Deno コマンドを実行した際の各種挙動をテストする場所。いわゆるインテグレーションテストのイメージに近いもの。specs テストではコマンドのアウトプットをテキストファイルで指定して、その出力とコマンドの出力が等しいかなどがチェックされる。テキストファイル内では各種ディレクティブが用意されていて、例えば `[WILDCARD]` ディレクティブを使うと、その箇所は任意文字列とマッチさせることが出来る。

# まとめ

この記事では Deno レポジトリのディレクトリ構造を解説しました。

# 参考

過去にもディレクトリ構造を解説しています。

https://qiita.com/kt3k/items/b56b7f357726edb4886a

https://qiita.com/kt3k/items/a61e2b1ad8818f97f0d0