Deno v1.0.0 がリリースされたということでマニュアルページを翻訳ッ🦕

<img src="https://camo.githubusercontent.com/68631b19ad7605c7f5f1f161f5dcc9452cc288f9/68747470733a2f2f64656e6f6c69622e6769746875622e696f2f686967682d7265732d64656e6f2d6c6f676f2f64656e6f5f68725f636972636c652e706e67" alt="Deno" width="300" />

[Deno v1.0.0 がリリースされた](https://deno.land/v1) ということで、Deno Manual のページを翻訳してみました。
Qiita に翻訳記事を掲載するのは適さないのかもしれませんが、日本では一番エンジニアにリーチしそうに思いましたので Qiita に投稿させて頂きました。

ベースにしたバージョンとコミットは以下のものになります。v1.0.0 のものではないですが、ご了承くださいｍｍ

* version: v1.0.0-rc1
* commit: https://github.com/denoland/deno/blob/6e287d951853ff38fb7002d31b9677c184ae6ffa/std/manual.md

原文では、 Compiler API などの unstable な機能の記述もありましたが、この翻訳では削除しています。

## 2020-08-18 追記

日本語訳を随時更新していく予定というページがありましたので、そちらのリンクを記載しておきます。
https://yoshixmk.github.io/deno-manual-ja/

## はじめに

Deno は、デフォルトでセキュアな JavaScript/TypeScript ランタイムであり、開発者に素晴らしい経験をもたらします。
Deno は、V8, Rust, Tokio によって作られています。

### 主な特徴について

- デフォルトでセキュアです。明示的に有効にしない限り、ファイル、ネットワーク、環境変数等にアクセスすることができません。
- TypeScript のコードを明示的なコンパイルなしで実行できます。
- 単一の実行可能なファイル(`deno`)のみがリリースされます。
- 依存の検査 (`deno info`) や コードフォーマット (`deno fmt`)などを実行する便利なサブコマンドが組み込まれています。
- Deno での動作が保証されている[標準モジュール](https://github.com/denoland/deno/tree/master/std)があります。
- 実行に必要な複数のスクリプトファイルを一つの JavaScript ファイルにバンドルする機能があります。

### 思想

Deno は、現代的なプログラマのための生産性と安全性が高いスクリプティング環境を目指しています。
Deno は、単一の実行可能ファイルでリリースされます。  
Given a URL to a Deno program, it is runnable with nothing more than [the ~15 megabyte zipped executable](https://github.com/denoland/deno/releases).
Deno は、ランタイムとパッケージマネージャーの両方の役割を持ちます。
モジュールの読み込みには、URLを利用した標準のブラウザ互換のプロトコルが使用されます。
Deno は、bash や Python で書かれたユーティリティースクリプトの優れた代替えになります。

### ゴール

- 単一の実行可能ファイル(`deno`)のみがリリースされる。
- 安全なデフォルト値を提供する。
  - 特に許可されていない限り、スクリプトはファイル、環境、ネットワークにアクセスできません。
- ブラウザとの互換性があります。JavaScriptのみで書かれており、グローバルな名前空間 `Deno` を使用していないDenoプログラムのサブセット(またはそのための機能テスト)は、最新のWebブラウザでも変更なく実行できるようにする必要があります。
- ユニットテスト、コードフォーマッター、リンターなどの組み込みツールを提供し、開発者の体験を向上させます。
- Does not leak V8 concepts into user land.
- 効率的に HTTP を扱える

### Node.js との比較

- Deno は npm を使いません
  * URL やファイルパスでモジュールを参照します。
- Deno はモジュール解決のアルゴリズムで `package.json` を使用しません。
- Deno のすべての非同期アクションは、Promise を返します。Deno は Node.js とは異なる API を提供します。
- Denoでは、ファイル、ネットワーク、環境変数へのアクセスに明示的な権限が必要です。
- エラーを捕捉しない場合は、Deno は常に終了します。
- "ES Modules"を使います。`require()` はサポートしません。サードパーティモジュールは、URLでインポートできます。

```javascript
import * as log from "https://deno.land/std/log/mod.ts";
```

### Other key behaviors

- リモートコードは最初の実行時にダウンロード・キャッシュされ、コードが `--reload` フラグで実行されるまで更新されません。
- URL からダウンロードされファイルは、不変でキャッシュ可能である必要があります。

### ロゴ

次のロゴは、Deno 本体と同様に、MITライセンスの下で配布されています(パブリックドメインでフリーで使用できます)。

- [A hand drawn one by @ry](https://deno.land/images/deno_logo.png)
- [An animated one by @hashrock](https://github.com/denolib/animated-deno-logo/)
- [A high resolution SVG one by @kevinkassimo](https://github.com/denolib/high-res-deno-logo)
- [A pixelated animation one by @tanakaworld](https://deno.land/images/deno_logo_4.gif)

## 組み込まれているユーティリティーとコマンド

- 依存検査 (`deno info`)
- コードフォーマッター (`deno fmt`)
- バンドリング (`deno bundle`)
- ランタイムの型情報 (`deno types`)
- テストランナー (`deno test`)
- デバッガ (`--debug`)
- リンター (`deno lint`) [coming soon](https://github.com/denoland/deno/issues/1880)

## セットアップ

Deno は、macOS, Linux, Windows で動作します。
Deno は、単一の実行可能なバイナリです。
外部の依存ファイルはありません。

### ダウンロードとインストール

[deno_install](https://github.com/denoland/deno_install) は、バイナリをダウンロードし、インストールするための便利なスクリプトを提供します。

シェルでインストール:

```shell
curl -fsSL https://deno.land/x/install/install.sh | sh
```

PowerShell でインストール:

```shell
iwr https://deno.land/x/install/install.ps1 -useb | iex
```

[Scoop](https://scoop.sh/) (Windows)でインストール:

```shell
scoop install deno
```

[Chocolatey](https://chocolatey.org/packages/deno) (Windows)でインストール:

```shell
choco install deno
```

[Homebrew](https://formulae.brew.sh/formula/deno) (macOS)でインストール:

```shell
brew install deno
```

[Cargo](https://crates.io/crates/deno) でインストール:

```shell
cargo install deno
```

Deno のバイナリは、 [github.com/denoland/deno/releases](https://github.com/denoland/deno/releases)から tar や zip ファイルをダウンロードし、手動でインストールすることもできます。
これらのパッケージには、実行可能ファイルが1つだけ含まれています。  
macOSとLinuxでは、実行可能ビットを設定する必要があります。

インストールし、環境変数 `PATH` を設定し、次を実行してみてください。

```shell
deno run https://deno.land/std/examples/welcome.ts
```

### インストール後の確認

インストール後に、`deno --version` を実行し確認します。
これでDenoバージョンがコンソールに出力されれば、インストールは成功しています。

deno コマンドのオプションと使用方法を確認したい場合は、`deno help` を実行してください。
サブコマンドのオプションを確認したい場合は、`deno help <subcommand>` を実行してください。

### バージョンアップ

Deno をバージョンアップするには、`deno upgrade` を実行します。

これは、[github.com/denoland/deno/releases](https://github.com/denoland/deno/releases) から最新のリリースを取得・解凍し、現在の実行ファイルを置き換えます。

### ソースからビルド

[コントリビュータ向けビルド手順](#development)を参照してください。

## 環境設定

Deno での開発の生産性をあげるために、環境を設定する必要があります。
シェルのオートコンプリート、環境変数、エディタや IDE の設定について説明します。

### 環境変数

Deno の動作を制御する環境変数があります:

`DENO_DIR` のデフォルトは `$HOME/.deno` ですが、生成されたソースコードやキャッシュされたソースコードの書き込み先や読み込み先を変更するために、任意のパスを設定することができます。

`NO_COLOR` を設定するとカラー出力が無効になります。
https://no-color.org/ を確認してください。
プログラムからは、boolean 定数 `Deno.noColor` を用いて `--allow-env` を指定せずに `NO_COLOR` が設定されているかどうかを確認することができます。

### シェル補完

`deno completions <shell>` コマンドを使用して、シェルの補完スクリプトを生成できます。
このコマンドは標準出力に出力するため、適切なファイルにリダイレクトする必要があります。

サポートシェル:

- zsh
- bash
- fish
- powershell
- elvish

例:

```shell
deno completions bash > /usr/local/etc/bash_completion.d/deno.bash
source /usr/local/etc/bash_completion.d/deno.bash
```

### エディタと IDEs

Deno のモジュールのインポートは、ファイル拡張子を指定することが可能であり、URL 形式でのインポートが可能です。
現時点では、ほとんどのエディターと Language Server ではこれをサポートしていないため、多くのエディターはエラーとして扱います。

コミュニティはこれらの問題を解決するために、いくつかのエディタ用の拡張機能を開発しました。

- [VS Code](https://marketplace.visualstudio.com/items?itemName=axetroy.vscode-deno)
  by [@axetroy](https://github.com/axetroy).

Support for JetBrains IDEs is not yet available, but you can follow and upvote these issues to stay up to date:
JetBrains IDE のサポートはまだ利用できませんが、これらの issue をフォローし、vote することができます。

- https://youtrack.jetbrains.com/issue/WEB-41607
- https://youtrack.jetbrains.com/issue/WEB-42983
- https://youtrack.jetbrains.com/issue/WEB-31667

## API リファレンス

### `deno types`

Deno のランタイムAPIの正確な情報を取得するには、コマンドラインで次のコマンドを実行します。

```shell
$ deno types
```

出力は、Deno に組み込まれている3つのライブラリファイルを連結したものです。

- [lib.deno.ns.d.ts](https://github.com/denoland/deno/blob/master/cli/js/lib.deno.ns.d.ts)
- [lib.deno.shared_globals.d.ts](https://github.com/denoland/deno/blob/master/cli/js/lib.deno.shared_globals.d.ts)
- [lib.deno.window.d.ts](https://github.com/denoland/deno/blob/master/cli/js/lib.deno.window.d.ts)

### 参考サイト

[TypeScript Deno API](https://deno.land/typedoc/index.html).

Rust プログラムに Deno を組み込みたい場合は、[Rust Deno API](https://docs.rs/deno) を参照してください。  

Deno クレートは、[crates.io](https://crates.io/crates/deno) にホストされています。

## Examples

### Unix の cat コマンドの実装

このプログラムでは、コマンドライン引数をファイル名とみなし、ファイルをオープンして標準出力に出力します。

```ts
for (let i = 0; i < Deno.args.length; i++) {
  let filename = Deno.args[i];
  let file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}
```

The `copy()` function here actually makes no more than the necessary kernel -> userspace -> kernel copies.
That is, the same memory from which data is read from the file, is written to stdout.  
これは、Deno の I/O ストリームの全般的な設計目標を示しています。

実行:

```shell
$ deno run --allow-read https://deno.land/std/examples/cat.ts /etc/passwd
```

### TCP echo server

これは、ポート8080で接続を受け入れ、送信されたものをクライアントに返す単純なサーバーの例です。

```ts
const listener = Deno.listen({ port: 8080 });
console.log("listening on 0.0.0.0:8080");
for await (const conn of listener) {
  Deno.copy(conn, conn);
}
```

このプログラムを起動すると、PermissionDeniedエラーが発生します。

```shell
$ deno run https://deno.land/std/examples/echo_server.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8080", run again with the --allow-net flag
► $deno$/dispatch_json.ts:40:11
    at DenoError ($deno$/errors.ts:20:5)
    ...
```

セキュリティ上の理由から、Denoは明示的な許可なしにプログラムがネットワークにアクセスすることを許可していません。  
ネットワークへのアクセスを許可するには、コマンドオプションを使用します。

```shell
$ deno run --allow-net https://deno.land/std/examples/echo_server.ts
```

テストするには、netcat を使用してデータを送信してみてください:

```shell
$ nc localhost 8080
hello world
hello world
```

`cat.ts` の例と同様に、ここでも `copy()` 関数は不要なメモリのコピーを作成しません。  
カーネルからのパケットを受信し、それ以上複雑な処理をせずに送り返します。

### 権限の確認と取り消し

プログラムによっては、以前に付与された権限を取り消すことが必要になる場合があります。
後の段階でプログラムが権限を必要とする場合、プログラムはエラーになります。

```ts
// 権限を確認する
const status = await Deno.permissions.query({ name: "write" });
if (status.state !== "granted") {
  throw new Error("need write permission");
}

const log = await Deno.open("request.log", "a+");

// 一部の権限を取り消す
await Deno.permissions.revoke({ name: "read" });
await Deno.permissions.revoke({ name: "write" });

// ログファイルを使う
const encoder = new TextEncoder();
await log.write(encoder.encode("hello\n"));

// これはエラーになります
await Deno.remove("request.log");
```

### File server

これは、HTTPサーバとしてローカルディレクトリを公開します。

```bash
deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
```

実行:

```shell
$ file_server .
Downloading https://deno.land/std/http/file_server.ts...
[...]
HTTP server listening on http://0.0.0.0:4500/
```

また、最新のバージョンにアップグレードしたい場合は、次のようにします:

```shell
$ file_server --reload
```

### 指定したモジュールの再読み込み

一部のモジュールのみをアップグレードしたい場合があります。`--reload` オプションで対象を指定することにより制御できます。

すべての再読み込み

`--reload`

すべての標準モジュールの再読み込み

`--reload=https://deno.land/std`

特定のモジュール（この例では、colors とファイルシステムユーティリティ）を再ロードするには、カンマを使用してURLを区切ります。

`--reload=https://deno.land/std/fs/utils.ts,https://deno.land/std/fmt/colors.ts`

### ホワイトリストによる権限指定

Deno は、ホワイトリストによる権限を指定する方法も提供しています。

これは、ホワイトリストでファイルシステムへのアクセスを制限する例です。

```shell
$ deno run --allow-read=/usr https://deno.land/std/examples/cat.ts /etc/passwd
error: Uncaught PermissionDenied: read access to "/etc/passwd", run again with the --allow-read flag
► $deno$/dispatch_json.ts:40:11
    at DenoError ($deno$/errors.ts:20:5)
    ...
```

`/etc` ディレクトリ配下の読み取り権限を付与できます。

```shell
$ deno run --allow-read=/etc https://deno.land/std/examples/cat.ts /etc/passwd
```

`--allow-write` は、 `--allow-read` と同様に使えます。

次は、ホスト名でネットワークへのアクセスを制限する例です。

```ts
const result = await fetch("https://deno.land/");
```

```shell
$ deno run --allow-net=deno.land https://deno.land/std/examples/curl.ts https://deno.land/
```

### 子プロセスの実行

[API リファレンス](https://deno.land/typedoc/index.html#run)

例:

```ts
// 子プロセスを生成する
const p = Deno.run({
  cmd: ["echo", "hello"],
});

// 完了を待機します
await p.status();
```

実行:

```shell
$ deno run --allow-run ./subprocess_simple.ts
hello
```

ここで関数が 'window.onload' に割り当てられます。
この関数は、メインスクリプトが読み込まれたあとに呼ばれます。
これは、Webブラウザの [onload](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload) と同じでエントリポイントとして利用できます。

`Deno.run()` で子プロセスを生成すると、デフォルトで 親プロセスの `stdin`, `stdout`, `stderr` を引き継ぎます。  
子プロセスと通信したい場合は、`"piped"` オプションが使用できます。

```ts
const fileNames = Deno.args;

const p = Deno.run({
  cmd: [
    "deno",
    "run",
    "--allow-read",
    "https://deno.land/std/examples/cat.ts",
    ...fileNames,
  ],
  stdout: "piped",
  stderr: "piped",
});

const { code } = await p.status();

if (code === 0) {
  const rawOutput = await p.output();
  await Deno.stdout.write(rawOutput);
} else {
  const rawError = await p.stderrOutput();
  const errorString = new TextDecoder().decode(rawError);
  console.log(errorString);
}

Deno.exit(code);
```

実行:

```shell
$ deno run --allow-run ./subprocess.ts <somefile>
[file content]

$ deno run --allow-run ./subprocess.ts non_existent_file.md

Uncaught NotFound: No such file or directory (os error 2)
    at DenoError (deno/js/errors.ts:22:5)
    at maybeError (deno/js/errors.ts:41:12)
    at handleAsyncMsgFromRust (deno/js/dispatch.ts:27:17)
```

### シグナルの捕捉

[API リファレンス](https://deno.land/typedoc/index.html#signal)

シグナルの捕捉には `Deno.signal()` 関数を使います。

```
for await (const _ of Deno.signal(Deno.Signal.SIGINT)) {
  console.log("interrupted!");
}
```

`Deno.signal()` は、プロミスとしても動作します。

```
await Deno.signal(Deno.Singal.SIGINT);
console.log("interrupted!");
```

シグナルの捕捉を止めたい場合、signal オブジェクトの `dispose()` メソッドを使います。

```
const sig = Deno.signal(Deno.Signal.SIGINT);
setTimeout(() => { sig.dispose(); }, 5000);

for await (const _ of sig) {
  console.log("interrupted");
}
```

上記の `for-await` ループは、5秒後に sig.dispose()が呼ばれ、終了します。

### ファイルシステムイベント

ファイルシステムのイベントをポーリングするには:

```ts
const watcher = Deno.watchFs("/");
for await (const event of watcher) {
  console.log(">>>> event", event);
  // { kind: "create", paths: [ "/foo.txt" ] }
}
```

イベントの正確な順序は、オペレーティングシステムによって異なる場合があることに注意してください。
この機能は、プラットフォームによって異なるシステムコールを使用します。

* Linux: inotify
* macOS: FSEvents
* Windows: ReadDirectoryChangesW

### サードパーティコードのインポート

前述の例では、Deno が URL からスクリプトを実行できることがわかりました。
Web ブラウザ上の JavaScript と同様に、Deno は URL から直接ライブラリをインポートできます。
次のコードは、URL を使用してアサーションライブラリをインポートしています。

```ts
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

Deno.test("t1", function () {
  assertEquals("hello", "hello");
});

Deno.test("t2", function () {
  assertEquals("world", "world");
});
```

実行:

```shell
$ deno run test.ts
running 2 tests
test t1 ... ok
test t2 ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

```

このプログラムの実行に `--allow-net`フラグを指定する必要はないですが、ネットワークにアクセスにしています。
ランタイムは、import で指定したファイルをダウンロードしディスクにキャッシュするための特別なアクセス権を持っています。

Denoは、環境変数 `$DENO_DIR` で指定されたディレクトリに import で指定したファイルをキャッシュします。
`$DENO_DIR` が指定されていない場合、デフォルトでシステムのキャッシュディレクトリになります。
次にプログラムを実行するときには、ダウンロードは行われません。
プログラムが変更されていなければ、再コンパイルもされません。

ディレクトリのデフォルト:

- Linux/Redox: `$XDG_CACHE_HOME/deno` または `$HOME/.cache/deno`
- Windows: `%LOCALAPPDATA%/deno` (`%LOCALAPPDATA%` = `FOLDERID_LocalAppData`)
- macOS: `$HOME/Library/Caches/deno`
- If something fails, it falls back to `$HOME/.deno`

**しかし、 `https://deno.land/` がダウンした場合はどうなりますか？**  
外部サーバーに依存することは、開発には便利ですが、本番環境では脆弱です。  
Production software should always bundle its dependencies.  
本番のソフトウェアは常に依存関係をバンドルする必要があります。
Deno では、`$DENO_DIR`ディレクトリでダウンロードした依存ファイルが管理されます。`$DENO_DIR`は、環境変数として指定できます。

**変更される可能性のあるURLを信頼するにはどうすればよいですか。**  
ロックファイルを使用(`--lock`オプションを指定)することで、期待どおりのコードを実行しているか確認できます。

**特定のバージョンをどのようにインポートしますか？**  
URLにバージョンを指定するだけです。
たとえば、次のURLは実行されるコードを完全に指定しています: `https://unpkg.com/liltest@0.0.5/dist/liltest.js`  
本番環境で `$DENO_DIR` にコードを保存する前述の手法と組み合わせると、実行される正確なコードを完全に指定し、ネットワークにアクセスせずにコードを実行できます。

**同じURLをそれぞれのファイルでインポートするのは扱いにくくありませんか。URLの1つが異なるバージョンのライブラリにリンクしている場合はどうなりますか？ 大規模なプロジェクトで、至るところで同じURLを書いてしまうと問題が発生しませんか？**  
解決策としては、 `deps.ts` ファイル（Node.js の` package.json`ファイルと同じ目的を果たす）を作成し、外部ライブラリをインポートおよび再エクスポートすることです。
例えば、大規模なプロジェクトで上記のアサーション・ライブラリを使用していたとします。
`"https://deno.land/std/testing/asserts.ts"`を各ファイルでインポートするのではなく、サードパーティのコードをエクスポートする `deps.ts`ファイルを作成し利用できます。

```ts
export {
  assert,
  assertEquals,
  assertStrContains,
} from "https://deno.land/std/testing/asserts.ts";
```

同じプロジェクト内では、 `deps.ts`からインポートして同じURLへの多くの参照を避けることができます:

```ts
import { assertEquals, runTests, test } from "./deps.ts";
```

この設計により、パッケージ管理ソフトウェア、中央集権型コードリポジトリ、余計なファイル形式が生み出す膨大な複雑さを回避できます。

### 型定義ファイルの利用

Deno のランタイムは、ファーストクラスの言語として JavaScript と TypeScript をサポートしています。
つまり、拡張子（または正しいメディアタイプを提供するサーバー）を含む完全修飾モジュール名が必要です。
Deno には曖昧なモジュール解決はありません。  

TypeScript コンパイラは、JavaScript モジュールに型を適用するために、拡張子のないモジュールと Node.js モジュール解決ロジックの両方に依存しています。

このギャップを埋めるために、Deno は、曖昧な解決に頼ることなく型定義ファイルを参照する3つの方法をサポートしています。  

#### コンパイラ ヒント

JavaScript モジュールをインポートしていて、そのモジュールの型定義の場所が分かってる場合は、インポート時に型定義を指定できます。  
これはコンパイラのヒントの形式を使います。
コンパイラーのヒントは、`.d.ts` ファイルの場所と、関連付けられている JavaScript コードを Deno に伝えます。
The hint is `@deno-types` and when specified the value will be used in the compiler instead of the JavaScript module.  
このヒントは `@deno-types` であり、指定された値はJavaScriptモジュールの代わりにコンパイラで使用されます。

例えば、 `foo.js` があり、その型定義ファイル ` foo.d.ts`である場合、コードは次のようになります:

```ts
// @deno-types="./foo.d.ts"
import * as foo from "./foo.js";
```

型定義ファイルを指定するパスは、モジュールのインポートと同じロジックで解決されます。つまり拡張子が必要で JavaScript フィアルと対応している必要があります。
リモート上のファイルを指定することも可能です。

このヒントは次の行の `import` 文 (または `export ... from` 文) に影響し、コンパイル時に指定されたモジュールの代わりに `@deno-types` の内容が使われます。

上記の例では、Deno コンパイラは './foo.js' の代わりに './foo.d.ts' を読み込みます。
Deno は、プログラムを実行するときに './foo.js' を読み込みます。

#### JavaScript ファイルのトリプルスラッシュ の リファレンスディレクティブ

Deno で使用したいモジュールをホスティングしていて型定義ファイルの場所を Deno に認識させたい場合は、コードの中でトリプルスラッシュディレクティブを利用することができます。
例えば、JavaScriptモジュールがあり、そのファイルと一緒にある型定義の場所を Deno に認識させたいとします。
`foo.js` は以下のようになるかもしれません。

```js
/// <reference types="./foo.d.ts" />
export const foo = "foo";
```

Denoはこれを認識し、コンパイラーはファイルの型チェック時に `foo.d.ts` を使用しますが、` foo.js` は実行時に読み込まれます。
ディレクティブは、モジュールのインポートと同じロジックで解決されます。つまり拡張子が必要で JavaScript ファイルと対応している必要があります。
リモート上のファイルを指定することも可能です。

#### カスタムヘッダー `X-TypeScript-Types`

使用するモジュールをホストしている場合は、カスタム HTTP ヘッダー `X-TypeScript-Types` を使用して、型定義ファイルの場所を Deno に認識させることができます。

このヘッダーは、前述のトリプルスラッシュリファレンスと同じように機能しますが、JavaScriptファイル自体のコンテンツを変更する必要がなく、型定義の場所をサーバー自体が決定できることを意味します。

**すべての型定義ファイルがサポートされているわけではありません。**

Deno はコンパイラヒントを使って指定された `.d.ts` ファイルをロードしますが、`.d.ts` ファイルの中にはサポートされていない機能が含まれているものもあります。
具体的には、`.d.ts` ファイルの中には、モジュールの解決ロジックを使って他のパッケージから型定義をロードしたり参照したりしているものがあります。
例えば、`node` を含む型参照ディレクティブは、`./node_modules/@types/node/index.d.ts` のようなパスに解決することを期待しています。
Since this depends on non-relative "magical" resolution, Deno cannot resolve this.

**TypeScript ファイルでトリプルスラッシュの型参照を使用しないのはなぜですか？**

TypeScript コンパイラは、型参照ディレクティブを含むトリプルスラッシュディレクティブをサポートしています。
Deno がこれを使うと TypeScript コンパイラの動作に支障をきたします。
Deno は JavaScript(とJSX)ファイル内のディレクティブのみを検索します。

<!--
### TypeScript ライブラリファイルの参照

When you use `deno run`, or other Deno commands which type check TypeScript, that code is evaluated against custom libraries which describe the environment that Deno supports.  
デフォルトでは、TypeScript の型チェックを行うコンパイラランタイム API も、これらのライブラリ(`Deno.compile()`, `Deno.bundle()`)を使用しています。

他のランタイム用に TypeScript をコンパイルまたはバンドルしたい場合は、デフォルトのライブラリをオーバーライドすることができます。
これを行うために、ランタイム API はコンパイラオプションの `lib` プロパティをサポートしています。
たとえば、Web ブラウザ向けのTypeScriptコードがある場合、TypeScript `"dom"` ライブラリを使用する必要があります:

```ts
const [errors, emitted] = await Deno.compile(
  "main.ts",
  {
    "main.ts": `document.getElementById("foo");\n`,
  },
  {
    lib: ["dom", "esnext"],
  }
);
```

TypeScript がサポートするすべてのライブラリのリストについては、 `lib` コンパイラオプションのドキュメントを参照してください。

**JavaScript ライブラリを含めることを忘れないでください**

`tsc` と同様に、` lib` コンパイラオプションを指定すると、デフォルトのものを上書きします。
つまり、基本的な JavaScript ライブラリは含まれず、最適な対象のランタイムを指定する必要があります(e.g. `es5`, `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020`, `esnext`)。

#### ネームスペース `Deno` を含める 

TypeScript によって提供されるライブラリに加えて、利用可能な Deno に組み込まれている4つのライブラリがあります。

- `deno.ns` - ネームスペース `Deno`
- `deno.shared_globals` - Deno が実行時にサポートするグローバルなインターフェースと変数を提供します。これらは、最終的にはランタイムライブラリによって提供されます。
- `deno.window` - グルーバル変数とネームスペース `Deno` に展開します。これは、Deno のメインワーカーで利用でき、ランタイムコンパイラ API のデフォルトです。
- `deno.worker` - Deno で利用できる Workers のグローバル変数

コンパイルにネームスペース Deno を含めるには、`lib` オプションの配列に `deno.ns` を含めます。

例:

```ts
const [errors, emitted] = await Deno.compile(
  "main.ts",
  {
    "main.ts": `document.getElementById("foo");\n`,
  },
  {
    lib: ["dom", "esnext", "deno.ns"],
  }
);
```

**注意** ネームスペース Deno は、少なくとも ES2018 以降のランタイム環境を想定しています。
つまり `lib` に ES2018 より低いものを指定するとコンパイルエラーが発生します。

#### トリプルスラッシュリファレンスの使用

コンパイラオプションで `lib` を指定する必要はありません。
Deno は、lib への[トリプルスラッシュレファレンス](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-lib-)もサポートしています。
それは、ファイルの中に記述できます。
たとえば、次のような `main.ts` があるとします:

```ts
/// <reference lib="dom" />

document.getElementById("foo");
```

次のようなコードで、エラーなしでコンパイルされます:

```ts
const [errors, emitted] = await Deno.compile("./main.ts", undefined, {
  lib: ["esnext"],
});
```

**注意** `dom` ライブラリは、Denoのデフォルトで定義されているグローバル変数と一部と競合することに注意してください。
これを回避するには、ランタイムコンパイラAPIのコンパイラオプションで `lib` オプションを指定する必要があります。

-->

### 現在のファイルがメインプログラムであるかどうかの判定

現在のスクリプトがメインプログラムとして実行されたかどうかを判定するには、`import.meta.main`をチェックしてください。

```ts
if (import.meta.main) {
  console.log("main");
}
```

## コマンドラインインターフェース

### V8 フラグ

V8 には多くの内部コマンドラインフラグがあります。

```shell
# 使用可能な V8 フラグを確認する
$ deno --v8-flags=--help

# 複数のフラグを使用する例
$ deno --v8-flags=--expose-gc,--use-strict
```

次のフラグは特に便利です。

```
--async-stack-trace
```

### バンドル

`deno bundle <source_file>` は、指定された `source_file` のすべての依存関係を含む単一の JavaScript ファイルを出力します。

例:

```
> deno bundle https://deno.land/std/examples/colors.ts colors.bundle.js
Bundling "colors.bundle.js"
Emitting bundle to "colors.bundle.js"
9.2 kB emitted.
```

パラメータの出力ファイルを省略すると、`stdout` に出力されます。

出力されたバンドルファイルは、他のモジュールと同様に実行できます:

```
deno run colors.bundle.js
```

出力されたバンドルファイルは自己完結型 ES モジュールで、コマンドラインで指定されたメインモジュールからのエクスポートが使用可能になります。

```ts
export { foo } from "./foo.js";

export const bar = "bar";
```

次のようにインポートできます:

```ts
import { foo, bar } from "./lib.bundle.js";
```

バンドルされたファイルは、Webブラウザでも読み込むことができます。
自己完結型のESモジュールであるため、 `type` の属性は `"module"` に設定する必要があります。

例:

```html
<script type="module" src="website.bundle.js"></script>
```

または、別のESモジュールにインポートして使用することもできます:

```html
<script type="module">
  import * as website from "website.bundle.js";
</script>
```

### 実行可能なスクリプトのインストール

Denoは、実行可能なファイルを簡単にインストールするための `deno install` を提供します。

`deno install [OPTIONS ...] [EXE_NAME] [URL] [SCRIPT_ARGS ...]` は、 `URL` で利用可能なスクリプトを指定し、` EXE_NAME` という名前でインストールします。

このコマンドは、指定されたCLIオプションとメインモジュールを使用して `deno`を呼び出す、小さい実行可能なシェルスクリプトを作成します。
シェルスクリプトは、インストールルートの `bin` ディレクトリ配下に配置されます。

例:

```shell
$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
[1/1] Compiling https://deno.land/std/http/file_server.ts

✅ Successfully installed file_server.
/Users/deno/.deno/bin/file_server
```

実行ファイル名を変更するには、`-n`/`--name` オプションを使います:

```shell
  deno install --allow-net --allow-read -n serve https://deno.land/std/http/file_server.ts
```

実行ファイル名が省略される場合、デフォルトで決定します:

- URL パスの最下層の名前を使用します。上記の例は `file_server` になります。
- If the file stem is something generic like 'main', 'mod', 'index' or 'cli', and the path has no parent, take the file name of the parent path. Otherwise settle with the generic name.

インストールルートを変更するには、`--root` オプションを使用します。

```shell
$ deno install --allow-net --allow-read --root /usr/local https://deno.land/std/http/file_server.ts
```

インストールルートは、次の優先順位で決定します:

- `--root` オプション
- 環境変数 `DENO_INSTALL_ROOT`
- `$HOME/.deno`

必要に応じて手動でパスに追加する必要があります。

```shell
$ echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.bashrc
```

インストール時にスクリプト実行に必要な権限を指定する必要があります。

```shell
$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts 8080
```

上記のコマンドは、参照権限で実行しポート8080にバインドする `file_server` という名前の実行可能ファイルを作成します。

[`import.meta.main`](#testing-if-current-file-is-the-main-program) を使って、実行可能なスクリプトのエントリポイントを指定すると良いでしょう。

例:

```ts
// https://example.com/awesome/cli.ts
async function myAwesomeCli(): Promise<void> {
  -- snip --
}

if (import.meta.main) {
  myAwesomeCli();
}
```

実行可能なスクリプトに関してユーザに共有する際は、インストールコマンドをドキュメントに記載してください。

```shell
# Install using deno install

$ deno install -n awesome_cli https://example.com/awesome/cli.ts
```

## プロキシ

Denoは、モジュールのダウンロードと `fetch` API のためのプロキシをサポートしています。  
プロキシの設定は環境変数 `HTTP_PROXY` と `HTTPS_PROXY` から読み込みます。  
Windows で環境変数が見つからない場合、レジストリからプロキシ情報を読み出します。  

## ロックファイル

Denoは、小さなJSONファイルを使用して、モジュールのサブリソースの整合性を保存およびチェックできます。
ロックファイルのチェックを有効し指定するには、`--lock=lock.json` オプションを使用します。
ロックファイルを更新または作成するには `--lock=lock.json --lock-write` オプションを使用します。

## Import maps

Deno は、 [import maps](https://github.com/WICG/import-maps) をサポートします。

deno コマンドの `--importmap=<FILE>` オプションで import map を指定できます。

現在の制限:

- 指定可能な import map は、一つのみです
- フォールバックURLは使えません
- ネームスペース `std:` をサポートしていません
- スキームは、`file:`, `http:`, `https:` のみサポートされます

例:  

```js
// import_map.json

{
   "imports": {
      "http/": "https://deno.land/std/http/"
   }
}
```

```ts
// hello_server.ts

import { serve } from "http/server.ts";

const body = new TextEncoder().encode("Hello World\n");
for await (const req of serve(":8000")) {
  req.respond({ body });
}
```

```shell
$ deno run --importmap=import_map.json hello_server.ts
```

## WASM サポート

Deno は、 [wasm](https://webassembly.org/) バイナリを実行できます。

<!-- prettier-ignore-start -->
```js
const wasmCode = new Uint8Array([
  0, 97, 115, 109, 1, 0, 0, 0, 1, 133, 128, 128, 128, 0, 1, 96, 0, 1, 127,
  3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0,
  5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145,
  128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97,
  105, 110, 0, 0, 10, 138, 128, 128, 128, 0, 1, 132, 128, 128, 128, 0, 0,
  65, 42, 11
]);
const wasmModule = new WebAssembly.Module(wasmCode);
const wasmInstance = new WebAssembly.Instance(wasmModule);
console.log(wasmInstance.exports.main().toString());
```
<!-- prettier-ignore-end -->

WASM ファイルは、`import` 文でも読み込むことができます:

```ts
import { fib } from "./fib.wasm";
console.log(fib(20));
```

<!--
## コンパイラAPI

Denoは、組み込みの TypeScript コンパイラへのランタイムアクセスをサポートしています。
名前空間 `Deno` には、このアクセスを提供する3つのメソッドがあります。

### `Deno.compile()`

これは `deno cache` と似たような動作をします。コードの取得とキャッシュ、コンパイルをしますが、実行はしません。
最大で3つの引数、 `rootName`、` sources`(オプション)、`options`(オプション)を取ります。  
`rootName` は、ルートモジュールです。
これは、`deno run --reload example.ts` でコマンドラインで渡すモジュール名と同じです。  
`sources` はハッシュであり、キーは完全修飾されたモジュール名、値はモジュールのソースのテキストです。
`sources` が指定された場合、Deno はそのハッシュ内からすべてのモジュールを解決し、Deno の外部では解決しません。
`sources` が指定されなかった場合、ルートモジュールがコマンドラインで指定されたときと同様にモジュールを解決します。
Deno は、この時のリソースもキャッシュします。  
`options` は、` Deno.CompilerOptions` 型で、これは、Deno でサポートされているオプションを含む TypeScript コンパイラオプションのサブセットです。

戻り値は、タプル型です。
最初の引数には、コードに関連するすべての診断結果（構文または型エラー）が含まれます。
2番目の引数は、キーが出力ファイル名で値がコンテンツであるマップです。

sources を指定する例:

```ts
const [diagnostics, emitMap] = await Deno.compile("/foo.ts", {
  "/foo.ts": `import * as bar from "./bar.ts";\nconsole.log(bar);\n`,
  "/bar.ts": `export const bar = "bar";\n`,
});

assert(diagnostics == null); // 診断結果が返ってこないことを確認する
console.log(emitMap);
```

マップには、 `/foo.js.map`,`/foo.js`, `/bar.js.map`, `/bar.js` という名前の4つのファイルが含まれます。

sources を指定しない場合は、コマンドラインで実行するのと同じように、ローカルモジュールまたはリモートモジュールを使用できます。

次のようなコードになります:

```ts
const [diagnostics, emitMap] = await Deno.compile(
  "https://deno.land/std/examples/welcome.ts"
);
```

この場合、`emitMap` には単純な `console.log()` 文が含まれます。

### `Deno.bundle()`

これは、コマンドラインの `deno bundle` と同じように機能します。
また、 `Deno.compile()` に似ていますが、ファイルのマップを返す代わりに、単一の文字列を返します。
これは、指定されたルートモジュールとその依存を含む、自己完結型の JavaScript ES モジュールです。
最大で3つの引数、 `rootName`、` sources`(オプション)、`options`(オプション)を取ります。  
`rootName` は、ルートモジュールです。
これは、`deno bundle example.ts` でコマンドラインで渡すモジュール名と同じです。  
`sources` はハッシュであり、キーは完全修飾されたモジュール名、値はモジュールのソースのテキストです。
`sources` が指定された場合、Deno はそのハッシュ内からすべてのモジュールを解決し、Deno の外部では解決しません。
`sources` が指定されなかった場合、ルートモジュールがコマンドラインで指定されたときと同様にモジュールを解決します。
Deno は、この時のリソースもキャッシュします。  
`options` は、` Deno.CompilerOptions` 型で、これは、Deno でサポートされているオプションを含む TypeScript コンパイラオプションのサブセットです。

sources を指定する例:

```ts
const [diagnostics, emit] = await Deno.bundle("/foo.ts", {
  "/foo.ts": `import * as bar from "./bar.ts";\nconsole.log(bar);\n`,
  "/bar.ts": `export const bar = "bar";\n`,
});

assert(diagnostics == null); // ensuring no diagnostics are returned
console.log(emit);
```

`emit` は、両方のモジュールの出力ソースを含む ES モジュールのテキストになります。

sources を指定しない場合は、コマンドラインで実行するのと同じように、ローカルモジュールまたはリモートモジュールを使用できます。

次のようなコードになります:

```ts
const [diagnostics, emit] = await Deno.bundle(
  "https://deno.land/std/http/server.ts"
);
```

この場合、`emit` は、依存関係のすべてを解決した自己完結型のJavaScript ES モジュールになります。

### `Deno.transpileOnly()`

This is based off of the TypeScript function `transpileModule()`.  
All this does is "erase" any types from the modules and emit JavaScript.  
There is no type checking and no resolution of dependencies. It accepts up to two arguments, the first is a hash where the key is the module name and the value is the content.
The only purpose of the module name is when putting information into a source map, of what the source file name was.  
The second argument contains optional `options` of the type `Deno.CompilerOptions`.  
The function resolves with a map where the key is the source module name supplied, and the value is an object
with a property of `source` and optionally `map`.  
The first is the output contents of the module.  
The `map` property is the source map. 
Source maps are provided by default, but can be turned off via the `options` argument.

An example:

```ts
const result = await Deno.transpileOnly({
  "/foo.ts": `enum Foo { Foo, Bar, Baz };\n`,
});

console.log(result["/foo.ts"].source);
console.log(result["/foo.ts"].map);
```

We would expect the `enum` would be rewritten to an IIFE which constructs the enumerable, and the map to be defined.

-->

## TypeScript のコンパイラオプション

Deno エコシステムを TypeScript の理想的な状態にするために、すべての `strict` フラグをデフォルトで有効にしています。
ただし、プログラムの実行時に `tsconfig.json` などの設定ファイルをオプションで指定することによりカスタマイズすることが可能です。
アプリケーションを実行するときに `-c` オプションを使い、設定ファイルを指定することができます。

```bash
deno run -c tsconfig.json mod.ts
```

設定可能な項目とデフォルトは、次のようになります:

```json
{
  "compilerOptions": {
    "allowJs": false,
    "allowUmdGlobalAccess": false,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "alwaysStrict": true,
    "assumeChangesOnlyAffectDirectDependencies": false,
    "checkJs": false,
    "disableSizeLimit": false,
    "generateCpuProfile": "profile.cpuprofile",
    "jsx": "react",
    "jsxFactory": "React.createElement",
    "lib": [],
    "noFallthroughCasesInSwitch": false,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitUseStrict": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveConstEnums": false,
    "removeComments": false,
    "resolveJsonModule": true,
    "strict": true,
    "strictBindCallApply": true,
    "strictFunctionTypes": true,
    "strictNullChecks": true,
    "strictPropertyInitialization": true,
    "suppressExcessPropertyErrors": false,
    "suppressImplicitAnyIndexErrors": false,
    "useDefineForClassFields": false
  }
}
```

許可される値と使用例に関するドキュメントについては、[TypeScript のドキュメント](https://www.typescriptlang.org/docs/handbook/compiler-options.html)を参照してください。


注：上記にリストされていないオプションは、Deno でサポートされていないか、TypeScriptドキュメントで非推奨/実験的としてリストされています。

## プログラムのライフサイクル

Deno は、Web ブラウザの JavaScript と互換のあるライフサイクルイベントをサポートしています: `load` と `unload`.  
これらのイベントを使用し、プログラムのセットアップとクリーンアップのコードを作成することができます。

`load`イベントのリスナーは非同期であり、待機します。
`unload` イベントのリスナーは同期している必要があります。
どちらのイベントもキャンセルできません。

例:

```typescript
// main.ts
import "./imported.ts";

const handler = (e: Event): void => {
  console.log(`got ${e.type} event in event handler (main)`);
};

window.addEventListener("load", handler);

window.addEventListener("unload", handler);

window.onload = (e: Event): void => {
  console.log(`got ${e.type} event in onload function (main)`);
};

window.onunload = (e: Event): void => {
  console.log(`got ${e.type} event in onunload function (main)`);
};

// imported.ts
const handler = (e: Event): void => {
  console.log(`got ${e.type} event in event handler (imported)`);
};

window.addEventListener("load", handler);
window.addEventListener("unload", handler);

window.onload = (e: Event): void => {
  console.log(`got ${e.type} event in onload function (imported)`);
};

window.onunload = (e: Event): void => {
  console.log(`got ${e.type} event in onunload function (imported)`);
};

console.log("log from imported script");
```

`window.addEventListener` と `window.onload`/`window.onunload` の両方を使用してイベントのハンドラーを定義できることに注意してください。
そこには大きな違いがあります。次の例を実行してみましょう：

```shell
$ deno run main.ts
log from imported script
log from main script
got load event in onload function (main)
got load event in event handler (imported)
got load event in event handler (main)
got unload event in onunload function (main)
got unload event in event handler (imported)
got unload event in event handler (main)
```

`window.addEventListener` を使用して追加されたすべてのリスナーが実行されましたが、`window.onload` および ` window.onunload` に関しては、`imported.ts` で定義されたものを ` main.ts` の定義がオーバーライドしています。

## `deno fmt`

Deno ships with a built in code formatter that auto-formats TypeScript and JavaScript code.
Denoには、TypeScript や JavaScript のコードを自動でフォーマットするコードフォーマッタが組み込まれています。

```shell
# 現在のディレクトリとサブディレクトリのすべての JS/TS ファイルをフォーマットする
deno fmt
# 指定したファイルをフォーマットする
deno fmt myfile1.ts myfile2.ts
# 現在のディレクトリとサブディレクトリのすべての JS/TS ファイルがフォーマットされているかどうかをチェックします
deno fmt --check
# 標準入力をフォーマットし、標準出力に書き込む
cat file.ts | deno fmt -
```

コードの前に `// deno-fmt-ignore` コメントをつけることでフォーマット対象から外します:

<!-- prettier-ignore-start -->

```ts
// deno-fmt-ignore
export const identity = [
    1, 0, 0,
    0, 1, 0,
    0, 0, 1,
];
```

<!-- prettier-ignore-end -->

また、ファイルの先頭に `// deno-fmt-ignore-file` コメントを追加することで、ファイル全体をフォーマット対象から外すことができます。

## 内部の詳細

### Deno と Linux の類否

|                       **Linux** | **Deno**                         |
| ------------------------------: | :------------------------------- |
|                       Processes | Web Workers                      |
|                        Syscalls | Ops                              |
|           File descriptors (fd) | [Resource ids (rid)](#resources) |
|                       Scheduler | Tokio                            |
| Userland: libc++ / glib / boost | https://deno.land/std/           |
|                 /proc/\$\$/stat | [Deno.metrics()](#metrics)       |
|                       man pages | deno types                       |

#### Resources

Resources（別名 `rid`）は、File descriptor の Deno バージョンです。
これは、オープンファイル、ソケット、その他のものを参照するために使用される整数値です。
次のコードでは、オープンしている Resources を確認しています。

```ts
const { resources, close } = Deno;
console.log(resources());
// { 0: "stdin", 1: "stdout", 2: "stderr" }
close(0);
console.log(resources());
// { 1: "stdout", 2: "stderr" }
```

#### メトリクス

メトリクスは、様々な統計情報のための内部カウンターです。

```shell
> console.table(Deno.metrics())
┌──────────────────┬────────┐
│     (index)      │ Values │
├──────────────────┼────────┤
│  opsDispatched   │   9    │
│   opsCompleted   │   9    │
│ bytesSentControl │  504   │
│  bytesSentData   │   0    │
│  bytesReceived   │  856   │
└──────────────────┴────────┘
```

### Schematic diagram

<img src="https://deno.land/images/schematic_v0.2.png">

### Profiling

To start profiling,

```sh
# Make sure we're only building release.
# Build deno and V8's d8.
ninja -C target/release d8

# Start the program we want to benchmark with --prof
./target/release/deno run --allow-net --v8-flags=--prof tests/http_bench.ts &

# Exercise it.
third_party/wrk/linux/wrk http://localhost:4500/
kill `pgrep deno`
```

V8 will write a file in the current directory that looks like this: `isolate-0x7fad98242400-v8.log`. To examine this file:

```sh
D8_PATH=target/release/ ./third_party/v8/tools/linux-tick-processor
isolate-0x7fad98242400-v8.log > prof.log
# on macOS, use ./third_party/v8/tools/mac-tick-processor instead
```

`prof.log` will contain information about tick distribution of different calls.

To view the log with Web UI, generate JSON file of the log:

```sh
D8_PATH=target/release/ ./third_party/v8/tools/linux-tick-processor
isolate-0x7fad98242400-v8.log --preprocess > prof.json
```

Open `third_party/v8/tools/profview/index.html` in your browser, and select `prof.json` to view the distribution graphically.

Useful V8 flags during profiling:

- --prof
- --log-internal-timer-events
- --log-timer-events
- --track-gc
- --log-source-code
- --track-gc-object-stats

To learn more about `d8` and profiling, check out the following links:

- [https://v8.dev/docs/d8](https://v8.dev/docs/d8)
- [https://v8.dev/docs/profile](https://v8.dev/docs/profile)

### LLDB を使用したデバッグ

LLDB を使用して Deno をデバッグできます。

```shell
$ lldb -- target/debug/deno run tests/worker.js
> run
> bt
> up
> up
> l
```

Rust コードをデバッグするには、 `rust-lldb` が使用できます。
それは、LLDB のラッパーであり、Rust の開発環境に含まれています。

```shell
$ rust-lldb -- ./target/debug/deno run --allow-net tests/http_bench.ts
# On macOS, you might get warnings like
# `ImportError: cannot import name _remove_dead_weakref`
# In that case, use system python by setting PATH, e.g.
# PATH=/System/Library/Frameworks/Python.framework/Versions/2.7/bin:$PATH
(lldb) command script import "/Users/kevinqian/.rustup/toolchains/1.36.0-x86_64-apple-darwin/lib/rustlib/etc/lldb_rust_formatters.py"
(lldb) type summary add --no-value --python-function lldb_rust_formatters.print_val -x ".*" --category Rust
(lldb) type category enable Rust
(lldb) target create "../deno/target/debug/deno"
Current executable set to '../deno/target/debug/deno' (x86_64).
(lldb) settings set -- target.run-args  "tests/http_bench.ts" "--allow-net"
(lldb) b op_start
(lldb) r
```

### Deno コア

Deno のコアは、[スタンドアローン crate](https://crates.io/crates/deno) としてリリースされます。
V8 自体がコアであり、"libdeno" という バインディング API があります。
詳細については、crate のドキュメントを参照してください。

### 継続的なベンチマークの計測

[こちら](https://deno.land/benchmarks.html)からベンチマークを参照してください。

ベンチマークチャートは、`//website/data.json` が `BenchmarkData[]` 型を持つものとします。
`BenchmarkData` は次のように定義されています。

```ts
interface ExecTimeData {
  mean: number;
  stddev: number;
  user: number;
  system: number;
  min: number;
  max: number;
}

interface BenchmarkData {
  created_at: string;
  sha1: string;
  benchmark: {
    [key: string]: ExecTimeData;
  };
  binarySizeData: {
    [key: string]: number;
  };
  threadCountData: {
    [key: string]: number;
  };
  syscallCountData: {
    [key: string]: number;
  };
}
```

## コントリビュート

- [style guide](style_guide.md) を参照してください。
- 今後のリリースに向けての進捗状況は[こちら](https://github.com/denoland/deno/milestones)で確認できます。
- [ベンチマーク](https://deno.land/benchmarks.html)を悪化させないでください。
- [コミュニティチャットルーム](https://discord.gg/TGMHGv6)で助けを求めましょう。
- Issue に取り組み始める前に Issue コメントにその旨を記載してください。

### 開発

#### レポジトリの clone

Linux や Mac での clone:

```bash
git clone --recurse-submodules https://github.com/denoland/deno.git
```

Windows のための追加の手順:

1. ["Developer Mode" を有効にしてください](https://www.google.com/search?q=windows+enable+developer+mode) (シンボリックリンクは管理者権限を必要とします).
2. git のバージョンが 2.19.2.2.windows.1 以降であることを確認してください。
3. checkout の前に、`core.symlinks=true` を設定してください。
   ```bash
   git config --global core.symlinks true
   git clone --recurse-submodules https://github.com/denoland/deno.git
   ```

#### 前提条件

Denoをビルドする最も簡単な方法は、V8のプリコンパイルバージョンを使用することです:

```
cargo build -vv
```

ソースコードから Deno と V8 をビルドしたい場合は、次のようになります:

```
V8_FROM_SOURCE=1 cargo build -vv
```

V8 をソースコードからビルドする場合、さらに次の依存があります:

`python` または `python.exe` が `PATH` 上に存在し、[Python 3 ではなく](https://github.com/denoland/deno/issues/464#issuecomment-411795578) Python 2 を参照していることを確認してください。


Linux の場合、glib-2.0 の開発ファイルもインストールする必要があります(Ubuntuの場合は、`apt install libglib2.0-dev` を実行してください)。

Mac の場合、[XCode](https://developer.apple.com/xcode/) をインストールする必要があります。

Windows の場合:

1. VS Community 2019 と Desktop development with C++ toolkit を取得し、 必須ツールと以下のすべての C++ ツールを選択してください。 

   - Visual C++ tools for CMake
   - Windows 10 SDK (10.0.17763.0)
   - Testing tools core features - Build Tools
   - Visual C++ ATL for x86 and x64
   - Visual C++ MFC for x86 and x64
   - C++/CLI support
   - VC++ 2015.3 v14.00 (v140) toolset for desktop

2. "Debugging Tools for Windows" を有効にしてください。 "Control Panel" → "Programs" → "Programs and Features" → Select "Windows Software Development Kit - Windows 10" → "Change" → "Change" → Check "Debugging Tools For Windows" → "Change" -> "Finish" と進みます。 
または、 [Debugging Tools for Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/) を使用します。(注意: ファイルをダウンロードし、手動で `X64 Debuggers And Tools-x64_en-us.msi` をインストールする必要があります)

V8 のビルドについての詳細は、[rusty_v8's README](https://github.com/denoland/rusty_v8) を参照してください。

#### ビルド

Cargo でビルドします:

```bash
# ビルド
cargo build -vv

# ビルドエラーが発生する場合、最新のマスターを使用していることを確認してからビルドをやり直してみてください
cargo clean && cargo build -vv

# 実行:
./target/debug/deno run cli/tests/002_hello.ts
```

#### Testing and Tools

Test `deno`:

```bash
# Run the whole suite:
cargo test

# Only test cli/js/:
cargo test js_unit_tests
```

Test `std/`:

```bash
cargo test std_tests
```

Lint the code:

```bash
./tools/lint.py
```

Format the code:

```bash
./tools/format.py
```

### プルリクエストの作成

プルリクエストを作成する前に、次の事が完了しているか確認してください。

1. 関連する Issue があり、それがPR文中で参照されていること
2. 変更をカバーするテストがある
3. `cargo test` が成功している
4. `tools/format.py` でコードをフォーマットしている
5. `./tools/lint.py` が成功している

### `third_party` の変更

`deno_third_party` では、何が利用されているか把握できるように、Deno に依存する外部コードを管理しています。
手作業とプライベートスクリプトにより慎重に管理されます。
変更を加えるためには、 @ry や @piscisaureus の助けが必要になる可能性があります。

### Ops の追加(aka bindings)

新しいAPIを追加するときに間違いを犯すことを非常に心配しています。
Deno に Op を追加する際には、他のプラットフォームでの該当インターフェースを調べる必要があります。
この機能が Go、Node、Rust、Python でどのようになっているかを列挙してください。

例として、[PR #671](https://github.com/denoland/deno/pull/671)で `Deno.rename()` がどのように提案され、追加されたかを参照してください。

### API のドキュメント作成

公開 API のドキュメントを作成することは重要であり、コードのインラインでそれを行いたいと考えています。
これにより、コードとドキュメントが緊密に結合されていることを確認することができます。

#### JSDoc の活用

`deno` モジュールとグローバル/`window` 名前空間を介して公開されているすべてのAPIとタイプには、JSDoc ドキュメントが必要です。
このドキュメントは解析され、TypeScript コンパイラで利用できるため、さらに他の場所で利用するのは簡単です。
JSDoc ブロックは、対象のコードの直前にあり、 `/**` で開始し `*/`で終了します。

例:

```ts
/** A simple JSDoc comment */
export const FOO = "foo";
```