前書き

deno-manual-jaGitHub stars

最終更新日 2020 年 8 月 16 日 deno @ a8f74aa

DenoはJavaScript / TypeScriptランタイムであり、安全なデフォルトと優れた開発者エクスペリエンスを備えています。

V8、Rust、Tokioに基づいて構築されています。

特徴

  • デフォルトでセキュアです。ファイル、ネットワーク、または環境変数へのアクセスをしません(明示的に有効にしない限り)。

  • TypeScriptがそのまま動作することをサポートしています。

  • 単一のコマンドで実行が可能 (deno)。

  • 依存関係の検査(deno info)やコードフォーマッター(deno fmt)などの組み込みユーティリティがあります。

  • Denoで動作が保証されている一連のレビュー(監査)済みの標準モジュールがあります。

  • スクリプトは、単一のJavaScriptファイルにバンドルできます。

哲学

Denoは、モダンなプログラマーにとって生産的で安全なスクリプト環境を目指しています。

Denoは常に単一の実行形式ファイルとして配布されます。 DenoへのプログラムのURLを指定すると、15MB以下の圧縮された実行可能ファイルを実行できます。 Denoは、ランタイムとパッケージマネージャーの両方の役割を明示的に行います。モジュールのロードに標準のブラウザ互換プロトコルとして、URLを使用します。

とりわけ、Denoは、歴史的にbashまたはpythonで作成されたユーティリティスクリプトの優れた代替品です。

目標

  • 単一の実行形式ファイルだけにする (deno)。

  • デフォルトでセキュアを提供する

    • 特に許可されていない限り、スクリプトはファイル、環境、またはネットワークにアクセスできません。
  • ブラウザー互換性:JavaScriptで完全に記述され、グローバルなDeno名前空間(またはその機能テスト)を使用しなければ、変更なしで最新のWebブラウザーで実行できます。

  • ユニットテスト、コードフォーマット、リンターなどの組み込みツールを提供して、開発者のエクスペリエンスを向上させます。

  • V8の概念をユーザーランドまで拡げません。

  • 効率的にHTTPを捌けます

Node.jsとの比較

  • Denoはnpmを使用しません。

    • URLまたはファイルパスとして参照されたモジュールを使用します。
  • Denoは、モジュール解決アルゴリズムでpackage.jsonを使用しません。

  • Denoにおいて、すべての非同期アクションにはPromiseを返します。したがって、DenoはNodeとは異なるAPIを提供します。

  • Denoは、ファイル、ネットワーク、および環境へのアクセスに明示的なパーミッションを必要とします。

  • Denoは常にエラーがどこにもキャッチされないとき、終了します。

  • 「ESモジュール」を使用し、require()をサポートしません。サードパーティのモジュールは、URLを介してインポートされます。

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

その他の主要な行動

  • リモートのコードは最初の実行時にフェッチしたのちにキャッシュされ、そのコードは--reloadフラグを使って実行されるまで更新されません。(したがって、飛行機でも機能します。)

  • リモートURLからロードされたモジュール/ファイルは、不変的にキャッシュできることを目指しています。

入門

この章では、以下について説明します。:

  • Denoのインストール
  • 環境のセットアップ
  • Hello Worldスクリプトの実行
  • 独自のスクリプト
  • コマンドラインインターフェース(CLI)
  • パーミッションについのて理解
  • TypeScriptの使用
  • WebAssemblyの使用

インストール方法

DenoはmacOS、Linux、およびWindowsで動作します。 Denoは単一のバイナリ実行ファイルです。外部依存関係はありません。

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

deno_installは、バイナリをダウンロードしてインストールするための便利なスクリプトを提供します。

Shellの場合 (macOS and Linux):

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

PowerShellの場合 (Windows):

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

Scoopの場合 (Windows):

scoop install deno

Chocolateyの場合 (Windows):

choco install deno

Homebrewの場合 (macOS):

brew install deno

Cargoの場合 (Windows, macOS, Linux):

cargo install deno

Denoのバイナリは github.com/denoland/deno/releases からZipファイルをダウンロードして、手動でインストールすることもできます。パッケージには、実行ファイルが1つだけ含まれています。macOSとLinuxは実行可能な成果物を選び設定する必要があります。

インストールのテスト

インストールをテストするには、deno --versionを実行します。もしDenoバージョンがコンソールに出力されれば、インストールは成功しています。

deno helpを使用すると、Denoのオプションのフラグと利用方法を確認できます。 CLIの詳細については、こちらをご確認ください。

アップデート

以前にインストールしたDenoのバージョンを更新するには、次のコマンドを実行します:

deno upgrade

これにより、github.com/denoland/deno/releasesから、最新のリリースを取得し、解凍され、現在の実行ファイルと置き換えられます。

次のユーティリティを使用して、特定のバージョンのDenoをインストールすることもできます:

deno upgrade --version 1.3.0

ソースからビルドする

ソースからビルドする方法についての情報は、貢献の章にあります。

環境セットアップ

Denoを生産的に使用するには、環境をセットアップする必要があります。つまり、シェルのオートコンプリート、環境変数、エディタ・IDEの設定を行います。

環境変数

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

環境変数DENO_DIRのデフォルトは $HOME/.cache/denoで、任意のパスに設定できますが、生成およびキャッシュされたソースコードの書き込みと読み取りを制御します。

もし、環境変数NO_COLORを設定すれば、カラー出力がオフになります。 https://no-color.org/を参照してください。NO_COLORを使用しているかのテストはソースコード内で、--allow-envなしで使用できるboolean定数のDeno.noColorを用いることで設定されているか確認ができます。

シェルのオートコンプリート

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

Deno がサポートしているシェルは次の通り:

  • zsh
  • bash
  • fish
  • powershell
  • elvish

例 (bash):

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

例 (フレームワークなしでのzsh):

mkdir ~/.oh-my-zsh/custom/plugins/deno
deno completions zsh > ~/.oh-my-zsh/custom/plugins/deno/_deno

次に、.zshrcに追加します。

fpath=(~/.zsh $fpath)
autoload -Uz compinit
compinit -u

それからターミナルを再起動します。補完がまだロードされない場合は、rm ~/.zcompdump/を実行して、以前に生成された補完を削除してから、compinitを実行してそれらを再度生成する必要があります。

例(zsh + oh-my-zsh)[zshユーザーに推奨]:

mkdir ~/.oh-my-zsh/custom/plugins/deno
deno completions zsh > ~/.oh-my-zsh/custom/plugins/deno/_deno

この後~/.zshrcファイルへdenoプラグインを追加します。antigenパスのようなツールの場合は~/.antigen/bundles/robbyrussell/oh-my-zsh/pluginsになり、コマンドはantigen bundle denoなどになります。

エディタとIDE

Denoはモジュールのインポートにファイル拡張子を使用する必要があり、さらにはhttpのインポートを許可が必要で、現在ほとんどのエディタと言語サーバーはこれをネイティブでサポートしていないため、多くのエディタは不要なファイル拡張子を持つファイルまたはインポートを見つけられないというエラーをスローします。

コミュニティは、一部の編集者がこれらの問題を解決するための拡張機能を開発しています:

VS Code

ベータバージョンの vscode_denoVisual Studio Marketplaceに公開されました。問題があればIssuesをください。

JetBrains IDE

JetBrains IDEのサポートは、the Deno pluginを通じて利用できます。

JetBrains IDEをDeno用に設定する方法の詳細については、YouTrackのこのコメントを参照してください。

Vim と NeoVim

もしCoC(intellisense engine and language server protocol)をインストールしていれば、Vim は Deno/TypeScript に対してかなりうまく機能します。

CoCをインストールした後、Vim内から:CocInstall coc-deno:CocInstall coc-denoを実行します。 Deno型定義でオートコンプリートを機能させるには、:CocCommand deno.typesを実行します。必要に応じて、:CocRestartでCoCサーバーを再起動します。これからは、gd(go to definition)やgr(goto/find references)などが機能するようになります。

Emacs

Emacsは、Emacs内でTypeScriptを使用する標準的な方法であるtideと、Denoの公式VSCode拡張機能で使用されるtypescript-deno-pluginの組み合わせを使用することにより、DenoをターゲットとするTypeScriptプロジェクトでかなりうまく機能します。

これを使用するには、まずEmacsのインスタンスにtideが設定されていることを確認してください。次に、 typescript-deno-plugin ページで指示されているように、最初に npm install --save-dev typescript-deno-plugin typescript (npm init -yが必須)を行い、次に下記のブロックをtsconfig.jsonに追加すれば準備完了です!

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "typescript-deno-plugin",
        "enable": true, // default is `true`
        "importmap": "import_map.json"
      }
    ]
  }
}

このリストにお気に入りのIDEがない場合は、拡張機能を開発するかもしれません。私たちのコミュニティのDiscordグループで、どこから始めればよいかについて、いくつか指針を差し上げることができます。

ファーストステップ

このページには、Denoの基礎について説明するいくつかの例が含まれています。

このドキュメントは、JavaScript、特にasync/awaitに関する予備知識があることを前提としています。 JavaScriptの予備知識がない場合は、Denoから始める前に、JavaScriptの基本に関するガイドに従うことをお勧めします。

Hello World

DenoはJavaScript / TypeScriptのランタイムであり、Web互換で、可能な限り最新の機能を使用しようとします。

ブラウザーの互換性は、DenoのHello Worldプログラムがブラウザーで実行できるプログラムと同じであることを意味します。

console.log("Welcome to Deno 🦕");

プログラムを試してください:

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

HTTPリクエストを行う

多くのプログラムは、HTTP要求を使用してWebサーバーからデータをフェッチします。ファイルをフェッチしてその内容を端末に出力する小さなプログラムを書いてみましょう。 ブラウザーと同様に、Web標準fetchAPIを使用してHTTP呼び出しを行うことができます。

const url = Deno.args[0];
const res = await fetch(url);

const body = new Uint8Array(await res.arrayBuffer());
await Deno.stdout.write(body);

このアプリケーションの機能を見ていきましょう。

  1. 最初の引数をアプリケーションに渡して、それをurl定数に格納します。

  2. 指定されたURLにリクエストを送信し、レスポンスを待って、res定数に格納します。

  3. 応答の本文をArrayBufferとして解析し、応答を待ち、Uint8Arrayに変換してbodyの定数に格納します。。

  4. body定数の内容をstdoutに書き込みます。

やってみよう:

deno run https://deno.land/std@0.65.0/examples/curl.ts https://example.com

このプログラムはネットワークアクセスに関するエラーを返しますが、何が問題だったのでしょうか。はじめに、Denoはデフォルトで安全なランタイムであることを紹介したのを覚えているかもしれません。つまり、ネットワークへのアクセスなど、「特権」アクションを実行する場合はパーミッションをプログラムに対して明示的に与える必要があります。

正しいパーミッションを与え、もう一度試してください:

deno run --allow-net=example.com https://deno.land/std@0.65.0/examples/curl.ts https://example.com

ファイルを読み取る

Denoは、Web以外のAPIも提供しています。これらはすべてDenoグローバルに含まれています。これらのAPIのドキュメントは、doc.deno.landにあります。

例えばファイルシステムAPIにはWeb標準形式がないため、Denoは独自のAPIを提供します。

このプログラムでは、各コマンドライン引数はファイル名であると想定され、ファイルが開かれ、標準出力に出力されます。

例:Unix cat

このプログラムでは、各コマンドライン引数はファイル名であると想定され、ファイルが開かれ、標準出力に出力されます。

const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}

ここのcopy()関数は、実際には必要なカーネル->ユーザースペース->カーネルのコピーしか作成しません。つまり、データがファイルから読み取られるのと同じメモリがstdoutに書き込まれます。これは、Denoの I/Oストリームの一般的な設計目標を示しています。

プログラムを試してください:

deno run --allow-read https://deno.land/std@0.65.0/examples/cat.ts /etc/passwd

TCP サーバー

例:TCP echo server

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

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エラーがスローされます。

$ deno run https://deno.land/std@0.65.0/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は明示的な許可なしにプログラムがネットワークにアクセスすることを許可していません。ネットワークへのアクセスを許可するには、コマンドラインフラグを使用します:

$ deno run --allow-net https://deno.land/std@0.65.0/examples/echo_server.ts

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

$ nc localhost 8080
hello world
hello world

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

他の例も見るには

HTTPファイルサーバーなどの例は、 の章にあります。

コマンドラインインターフェース(CLI)

Denoはコマンドラインプログラムです。これまでの例に従ってきたいくつかの簡単なコマンドに精通し、シェルの使用法の基本を理解している必要があります。

メインのヘルプテキストを表示する方法はいくつかあります。

# Using the subcommand.
deno help

# Using the short flag -- outputs the same as above.
deno -h

# Using the long flag -- outputs more detailed help text where available.
deno --help

DenoのCLIはサブコマンドベースです。上記のコマンドは、deno bundleなど、サポートされているもののリストを表示します。 bundleのサブコマンド固有のヘルプを表示するには、同様に次のいずれかを実行できます。

deno help bundle
deno bundle -h
deno bundle --help

各サブコマンドの詳細なガイドはこちらにあります。

スクリプト

Denoは、複数のソース、ファイル名、URL、および「-」を用いてstdinからファイルを読み取りスクリプトを取得して、実行することができます。最後のは他のアプリケーションとの統合に役立ちます。

deno run main.ts
deno run https://mydomain.com/main.ts
cat main.ts | deno run -

スクリプト引数

Denoランタイムフラグとは別に、スクリプト名の後にユーザースペース引数を指定して、実行中のスクリプトに渡すことができます。

deno run main.ts a b -c --quiet
// main.ts
console.log(Deno.args); // [ "a", "b", "-c", "--quiet" ]

スクリプト名の後に渡されたものはすべてスクリプト引数として渡され、Denoランタイムフラグとしては消費されないことに注意してください。 これは、次のような落とし穴につながります:

# Good. We grant net permission to net_client.ts.
deno run --allow-net net_client.ts

# Bad! --allow-net was passed to Deno.args, throws a net permission error.
deno run net_client.ts --allow-net

一部の人は、それを型破りなものと感じるかもしれません:

非定位置フラグは、その位置に応じて異なる方法で解析されます。

しかしながら:

  1. これは、ランタイムフラグとスクリプト引数を区別する最も論理的な方法です。
  2. これは、ランタイムフラグとスクリプト引数を区別する最も人間工学的な方法です。
  3. これは実際には、他の一般的なランタイムと同じ動作です。
    • node -c index.jsnode index.js -cを試してみます。すると1つ目は、ノードの-cフラグに従って、index.jsの構文チェックのみを実行します。2番目は、require("process").argv-cを渡してindex.jsを実行します。

関連するサブコマンド間で共有されるフラグの論理グループが存在します。これらについては以下で説明します。

整合性フラグ

リソースをキャッシュにダウンロードできるコマンドに影響を与えます:deno cachedeno rundeno test

--lock <FILE>    Check the specified lock file
--lock-write     Write lock file. Use with --lock.

これらの詳細については、こちらをご覧ください。

キャッシュとコンパイルのフラグ

キャッシュにデータを入力できるコマンドに影響を与えます:deno cachedeno rundeno test。上記のフラグに加えて、これにはモジュールの解決、コンパイル構成などに影響するフラグが含まれます。

--config <FILE>               Load tsconfig.json configuration file
--importmap <FILE>            UNSTABLE: Load import map file
--no-remote                   Do not resolve remote modules
--reload=<CACHE_BLOCKLIST>    Reload source code cache (recompile TypeScript)
--unstable                    Enable unstable APIs

ランタイムフラグ

ユーザーコードを実行するコマンドに影響を与えます:deno runおよびdeno test。これらには、上記のすべてと次のものが含まれます。

パーミッションフラグ

これらはこちらにリストされています。

その他のランタイムフラグ

実行環境に影響を与えるその他のフラグ:

--cached-only                Require that remote dependencies are already cached
--inspect=<HOST:PORT>        activate inspector on host:port ...
--inspect-brk=<HOST:PORT>    activate inspector on host:port and break at ...
--seed <NUMBER>              Seed Math.random()
--v8-flags=<v8-flags>        Set V8 command line options. For help: ...

パーミッション

Denoはデフォルトで安全です。したがって、特に有効にしない限り、denoモジュールには、ファイル、ネットワーク、環境などのアクセス権がありません。セキュリティ上重要な領域や機能にアクセスするには、コマンドラインでdenoプロセスに許可を与える必要があります。

次の例では、mod.tsにファイルシステムへの読み取り専用アクセスが許可されています。それに書き込むことも、その他の機密性の高い機能を実行することもできません。

deno run --allow-read mod.ts

パーミッションのリスト

次のパーミッションを使用できます:

  • -A, --allow-all すべてのパーミッションを許可します。これにより、すべてのセキュリティが無効になります。
  • --allow-env 環境変数の取得や設定などの環境アクセスを許可します。
  • --allow-hrtime 高分解能の時間測定を可能にします。高解像度の時間は、タイミング攻撃やフィンガープリントに使用できます。
  • --allow-net=<allow-net> ネットワークアクセスを許可します。オプションのドメインのコンマ区切りリストを指定して、許可されたドメインの許可リストを提供できます。
  • --allow-plugin プラグインの読み込みを許可します。 --allow-pluginは不安定な機能であることに注意してください。
  • --allow-read=<allow-read> ファイルシステムの読み取りアクセスを許可します。オプションのコンマ区切りのディレクトリまたはファイルのリストを指定して、許可されたファイルシステムアクセスの許可リストを提供できます。
  • --allow-run サブプロセスの実行を許可します。サブプロセスはサンドボックスで実行されないため、denoのプロセスと同じくセキュリティ制限がないことに注意してください。したがって、注意して使用してください。
  • --allow-write=<allow-write> ファイルシステムの書き込みアクセスを許可します。オプションのコンマ区切りのディレクトリまたはファイルのリストを指定して、許可されたファイルシステムアクセスの許可リストを提供できます。

パーミッション許可リスト

Denoでは、許可リストを使用して一部のパーミッションの細かさを制御することもできます。

この例では、/usrディレクトリのみを許可リストすることによってファイルシステムアクセスを制限していますが、プロセスが/etcディレクトリ内のファイルにアクセスしようとしたため、実行は失敗します。

$ deno run --allow-read=/usr https://deno.land/std@0.65.0/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を許可リストに加え、正しいパーミッションでもう一度試してください:

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

--allow-write--allow-readと同じように機能します

ネットワークアクセス

fetch.ts:

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

これは、ホスト/ URLを許可するリストの例です:

deno run --allow-net=github.com,deno.land fetch.ts

もしfetch.tsが他のドメインへのネットワーク接続を確立しようとすると、プロセスは失敗します。

すべてのホスト/ URLへの呼び出しを許可:

deno run --allow-net fetch.ts

TypeScriptの使用

Denoは、実行時にファーストクラス言語としてJavaScriptとTypeScriptの両方をサポートします。つまり、拡張子(または正しいメディアタイプを提供するサーバー)を含む完全修飾モジュール名が必要です。さらに、Denoには「魔法の」モジュール解決策がありません。代わりに、インポートされたモジュールは、ファイル(拡張子を含む)または完全修飾URLインポートとして指定されます。 Typescriptモジュールは直接インポートできます。例えば:

import { Response } from "https://deno.land/std@0.65.0/http/server.ts";
import { queue } from "./collections.ts";

--no-check オプション

deno rundeno testdeno cachedeno infodeno bundleを使用する場合、--no-checkフラグを指定してTypeScriptタイプのチェックを無効にすることができます。これにより、プログラムの起動にかかる時間を大幅に短縮できます。これは、エディタによって型チェックが提供され、起動時間をできるだけ速くしたい場合(ファイルウォッチャーでプログラムを自動的に再起動する場合など)に非常に役立ちます。

--no-checkはTypeScriptの型チェックを行わないため、型情報が必要になるため、型のみのインポートとエクスポートを自動的に削除することはできません。この目的のために、TypeScriptはimportタイプとexportタイプの構文を提供します。タイプを別のファイルにエクスポートするには、export type {AnInterface} from "./mod.ts";を使用します。タイプをインポートするには、 import type { AnInterface } from "./mod.ts";を使用します。 importsNotUsedAsValues TypeScriptコンパイラオプションを"error"に設定することで、必要に応じてインポートタイプとエクスポートタイプを使用していることを確認できます。このオプションを使用したtsconfig_test.jsonの例は、標準ライブラリ内にあります。

--no-checkを使用すると型情報がないため、const enumは型の指定であるためサポートされません。--no-checkは、従来のimport =およびexport =構文もサポートしていません。

外部型定義の使用

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

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

コンパイラーへのヒント

JavaScriptモジュールをインポートしていて、そのモジュールの型定義の場所がわかっている場合は、インポート時に型定義を指定できます。これでコンパイラへヒントを与えた形になります。コンパイラーへのヒントは、.d.tsファイルの場所と、それらが関連付けられているインポートされたJavaScriptコードをDenoに通知します。ヒントは@deno-typesであり、指定すると、JavaScriptモジュールの代わりにコンパイラで値が使用されます。

例えば、foo.jsがあったが、それに加えてファイルのタイプであるfoo.d.tsであることがわかっている場合、コードは次のようになります:

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

値は、モジュールのインポートと同じ解決ロジックに従います。つまり、ファイルには拡張子が必要であり、現在のモジュールに対して相対的です。リモート指定子も使用できます。

ヒントは、@deno-typesの値が、指定されたモジュールの代わりにコンパイル時に置換される次のimportステートメント(またはexport ... fromステートメント)に影響します。上記の例のように、Denoコンパイラは./foo.jsではなく./foo.d.tsをロードします。 Denoはプログラムの実行時に./foo.jsを引き続きロードします。

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

Denoで使用するモジュールをホストしていて、型定義の場所についてDenoに通知する場合は、実際のコードでトリプルスラッシュディレクティブを使用できます。例えば、JavaScriptモジュールがあり、そのファイルの横にある型定義の場所をDenoに提供する場合、foo.jsという名前のJavaScriptモジュールは次のようになります。:

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

Denoはこれを確認し、コンパイラはファイルの型チェック時にfoo.d.tsを使用しますが、foo.jsは実行時にロードされます。ディレクティブの値の解決は、モジュールのインポートと同じ解決ロジックに従います。つまり、ファイルには拡張子が必要であり、現在のファイルに対して相対的です。リモート指定子も使用できます。

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

Denoによって使用されるモジュールをホストしていて、Denoに型定義の場所を通知する場合は、X-TypeScript-TypesのカスタムHTTPヘッダーを使用して、そのファイルの場所をDenoに通知できます。

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

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

Denoはコンパイラヒントを使用して、指定された.d.tsファイルをロードしますが、一部の.d.tsファイルにはサポートされていない機能が含まれています。具体的には、一部の.d.tsファイルは、モジュール解決ロジックを使用して、他のパッケージから型定義をロードまたは参照できると想定しています。例えば、nodeを含める型の参照ディレクティブは、。./node_modules/@types/node/index.d.tsのようなパスに解決されることを期待しています。これは相対的でない「魔法の」解像度に依存するため、Denoはこれを解決できません。

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

TypeScriptコンパイラは、型の参照ディレクティブを含むトリプルスラッシュディレクティブをサポートします。 Denoがこれを使用した場合、TypeScriptコンパイラの動作に干渉します。 DenoはJavaScript(およびJSX)ファイルでディレクティブを検索するだけです。

カスタムTypeScriptコンパイラオプション

Denoエコシステムでは、デフォルトでstrict(=厳格)であるというTypeScriptの理想に準拠するために、すべての厳格なフラグが有効になっています。ただし、カスタマイズをサポートする方法を提供するために、プログラムの実行時にtsconfig.jsonなどの構成ファイルがDenoに提供される場合があります。

アプリケーションを実行するときに-C(または--config)引数を設定して、この構成を探す場所をDenoに明示的に指示する必要があります。

deno run -c tsconfig.json mod.ts

以下は、現在Denoで許可されている設定とそのデフォルト値です:

{
  "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 docsをご覧ください。.

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

WebAssembly 支持

DenoはWebAssemblyバイナリを実行できます。

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());

ランタイム

すべてのランタイム関数(Web API + Denoグローバル)の ドキュメントは、doc.deno.landにあります。

Web API

HTTPリクエストのためのfetchのように、Web標準がすでに存在するAPIの場合、Denoは新しい独自のAPIを発明するのではなく、これらを使用します。

実装されたWeb APIの詳細なドキュメントは、doc.deno.landにあります。さらに、Denoが実装するWeb APIの完全なリストは、リポジトリにもあります。

実装されたWeb APIのTypeScript定義は、 lib.deno.shared_globals.d.ts および lib.deno.window.d.tsファイルにあります。

ワーカー固有の定義はlib.deno.worker.d.tsファイルにあります。

Denoグローバル

Web標準ではないすべてのAPIは、グローバルなDeno名前空間に含まれています。ファイルからの読み取り、TCPソケットのオープン、サブプロセスの実行などのためのAPIを備えています。

Deno名前空間のTypeScript定義は lib.deno.ns.d.tsファイルにあります。

Deno固有のすべてのAPIのドキュメントは、 doc.deno.landにあります。

安定

Deno 1.0.0以降、Deno名前空間APIは安定しています。つまり、1.0.0で動作するコードが今後のバージョンでも引き続き動作するように努めます。

ただし、Denoの機能のすべてがまだプロダクションの準備ができているわけではありません。まだドラフト段階にあるため準備ができていない機能は、--unstableコマンドラインフラグでロックされています。

deno run --unstable mod_which_uses_unstable_stuff.ts

このフラグを渡すと、いくつかのことが行われます。

  • 実行時に不安定なAPIを使用できるようにします。
  • lib.deno.unstable.d.ts型チェックに使用されるTypeScript定義のリストにファイルを追加します。deno typesにはこの出力が含まれます。

多くの不安定なAPIはセキュリティレビューを受けておらず、将来APIに破壊的な変更が加えられる可能性があり、本稼働の準備ができていないことに注意してください。

標準モジュール

Denoの標準モジュール(https://deno.land/std/)はまだ安定していません。現在、これを反映するために、CLIとは異なる方法で標準モジュールをバージョン管理しています。Deno名前空間とは異なり、標準モジュールの使用には--unstableフラグが不要であることに注意してください(標準モジュール自体が不安定なDeno機能を使用しない限り)。

ライフサイクル

Denoは、ブラウザの互換性のあるloadunloadのライフサイクルイベントをサポートしています。これらのイベントを使用して、プログラムにセットアップコードとクリーンアップコードを提供できます。

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

例:

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)`);
};

console.log("log from main script");

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.addEventListenerwindow.onload / window.onunloadの両方を使用して、イベントのハンドラーを定義できることに注意してください。それらの間には大きな違いがあります。例を実行してみましょう:

$ 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を使用して追加されたすべてのリスナーが実行されましたが、main.tsで定義されたwindow.onloadおよびwindow.onunloadは、imported.tsで定義されたハンドラーをオーバーライドしました。

つまり、複数のwindow.addEventListener "load"または "unload"イベントを登録できますが、最後に読み込まれたwindow.onloadまたはwindow.onunloadイベントのみが実行されます。

コンパイラAPI

これは不安定なDeno機能です。不安定な機能の詳細をご覧ください。

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

Deno.compile()

これはdeno cacheと同様に機能し、コードのフェッチ、キャッシュ、コンパイルはできますが、実行はできません。これは、最大3つの引数で、rootNameと、オプションでsourcesoptionsを取ります。 rootNameは、結果のプログラムを生成するために使用されるルートモジュールです。これは、deno run --reload example.tsのコマンドラインで渡すモジュール名に似ています。sourcesはハッシュであり、キーは完全修飾モジュール名であり、値はモジュールのテキストソースです。sourcesが渡された場合、Denoはそのハッシュ内からすべてのモジュールを解決し、Denoの外部では解決を試みません。ソースが提供されない場合、Denoは、ルートモジュールがコマンドラインで渡されたかのようにモジュールを解決します。 Denoはこれらのリソースもキャッシュします。解決されたすべてのリソースは動的インポートとして扱われ、ローカルかリモートかに応じて読み取りまたはネットへのパーミッションが必要です。 options引数は、Deno.CompilerOptionsタイプのオプションのセットです。これは、Denoでサポートされているオプションを含むTypeScriptコンパイラオプションのサブセットです。

メソッドはタプルで解決されます。最初の引数には、コードに関連するすべての診断(構文または型エラー)が含まれます。 2番目の引数は、キーが出力ファイル名で値がコンテンツであるマップです。

ソースを提供する例:

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); // ensuring no diagnostics are returned
console.log(emitMap);

mapには、/foo.js.map/foo.js/bar.js.map/bar.jsという名前の4つの「ファイル」が含まれていると予想されます。

リソースを提供しない場合は、コマンドラインで行うのと同じように、ローカルモジュールまたはリモートモジュールを使用できます。だからあなたはこのようなことをすることができます:

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

この場合、emitMapにはconsole.log()ステートメントが含まれます。

Deno.bundle()

これは、コマンドラインでdeno bundleが行うのとよく似ています。これもDeno.compile()に似ていますが、ファイルのマップを返す代わりに、提供または解決されたすべてのコードとエクスポートを含む自己完結型のJavaScript ESモジュールである単一の文字列を返します。提供されたルートモジュールのすべてのエクスポートのこれは、最大3つの引数で、rootName、オプションでsourcesoptionsを取ります。 rootNameは、結果のプログラムを生成するために使用されるルートモジュールです。これは、deno bundle example.tsのコマンドラインで渡すモジュール名に似ています。sourcesはハッシュで、キーは完全修飾モジュール名であり、値はモジュールのテキストソースです。sourcesが渡された場合、Denoはそのハッシュ内からすべてのモジュールを解決し、Denoの外部では解決を試みません。sourcesが提供されない場合、Denoは、ルートモジュールがコマンドラインで渡されたかのようにモジュールを解決します。解決されたすべてのリソースは動的インポートとして扱われ、ローカルかリモートかに応じて読み取りまたはネットへのパーミッションが必要です。 Denoはこれらのリソースもキャッシュします。 options引数は、Deno.CompilerOptionsタイプのオプションのセットです。これは、Denoでサポートされているオプションを含むTypeScriptコンパイラオプションのサブセットです。

ソースを提供する例:

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モジュールのテキストであることを期待します。

リソースを提供しない場合は、コマンドラインで行うのと同じように、ローカルモジュールまたはリモートモジュールを使用できます。だからあなたはこのようなことをすることができます:

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

この場合、emitは、すべての依存関係が解決され、ソースモジュールと同じエクスポートを出力する、自身を含むJavaScript ESモジュールになります。

Deno.transpileOnly()

これは、TypeScript関数transpileModule()に基づいています。これが行うことは、モジュールからすべての型を「消去」し、JavaScriptを出力します。型チェックや依存関係の解決はありません。最大2つの引数を受け入れます。最初の引数は、キーがモジュール名で値がコンテンツであるハッシュです。モジュール名の唯一の目的は、ソースファイル名とは何か、ソースマップに情報を入れるときです。 2番目の引数には、Deno.CompilerOptions型のoptionsオプションが含まれます。関数はmapで解決されます。キーは指定されたソースモジュール名であり、値はsourceと必要に応じてmapのプロパティを持つオブジェクトです。 1つ目は、モジュールの出力内容です。 mapプロパティはソースマップです。ソースマップはデフォルトで提供されますが、options引数を介してオフにすることができます。

例:

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);

enumは、列挙可能な構成のIIFEに書き換えられ、マップが定義されることを期待します。

TypeScriptライブラリファイルの参照

deno runを使用する時、またはTypeScriptを型チェックする他のDenoコマンドを使用した時、そのコードはDenoがサポートする環境を記述するカスタムライブラリに対して評価されます。デフォルトでは、TypeScriptを型チェックするコンパイラランタイムAPIもこれらのライブラリ(Deno.compile()およびDeno.bundle())を使用します。

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

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

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

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

tscと同様に、libコンパイラオプションを指定すると、デフォルトのオプションが上書きされるため、基本的なJavaScriptライブラリは、対象のランタイムを最もよく表すものを含める必要があります(例えば、es5es2015es2016es2017es2018es2019es2020, esnext)。

Deno名前空間を含める

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

  • deno.ns - Denoの名前空間を提供します
  • deno.shared_globals - Denoが使用するグローバルインターフェイスと変数を提供します
  • deno.window - グローバル変数とDeno名前空間を公開します。
  • deno.worker - Denoの下のワーカーで使用可能なグローバル変数を公開します。

したがって、Deno名前空間をコンパイルに追加するには、deno.ns libを配列に含めます。例えば:

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

注意 Deno名前空間は、少なくともES2018以降のランタイム環境を想定していること。つまり、ES2018より「低い」libを使用すると、コンパイルの一部としてエラーがログに記録されます。

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

コンパイラオプションでlibを指定する必要はありません。 Denoは、libへのトリプルスラッシュ参照もサポートしています。ファイルのコンテンツに埋め込むことができます。例えば、次のようなmain.tsがあるとします。

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

document.getElementById("foo");

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

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

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

Workers

DenoはWeb Worker APIをサポートしています。

Workerを使用して、複数のスレッドでコードを実行できます。 Workerの各インスタンスは、そのWorker専用の個別のスレッドで実行されます。

現在、DenoはモジュールタイプのWorkerのみをサポートしています。したがって、新しいWorkerを作成するときは、type: "module"オプションを渡すことが不可欠です。

現在のところ、相対モジュール指定子はサポートされていません。代わりに、URLコンストラクターとimport.meta.urlを使用して、近くにあるスクリプトの指定子を簡単に作成できます。

// Good
new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });

// Bad
new Worker(new URL("worker.js", import.meta.url).href);
new Worker(new URL("worker.js", import.meta.url).href, { type: "classic" });
new Worker("./worker.js", { type: "module" });

パーミッション

新しいWorkerインスタンスの作成は、動的インポートに似ています。したがって、Denoはこのアクションに適切な許可を必要とします。

ローカルモジュールを使用するWorker向け。 --allow-readパーミッションが必要です。

main.ts

new Worker(new URL("worker.ts", import.meta.url).href, { type: "module" });

worker.ts

console.log("hello world");
self.close();
$ deno run main.ts
error: Uncaught PermissionDenied: read access to "./worker.ts", run again with the --allow-read flag

$ deno run --allow-read main.ts
hello world

リモートモジュールを使用するWorker向け。--allow-netパーミッションが必要です:

main.ts

new Worker("https://example.com/worker.ts", { type: "module" });

worker.ts

console.log("hello world");
self.close();
$ deno run main.ts
error: Uncaught PermissionDenied: net access to "https://example.com/worker.ts", run again with the --allow-net flag

$ deno run --allow-net main.ts
hello world

WorkerでのDenoの使用

これは不安定なDeno機能です。不安定な機能の詳細をご覧ください。

デフォルトでは、Deno名前空間はWorkerスコープでは使用できません。

新しいWorkerを作成するときにDeno名前空間に渡すにはdeno:trueオプションを追加します:

main.js

const worker = new Worker(new URL("worker.js", import.meta.url).href, {
  type: "module",
  deno: true,
});
worker.postMessage({ filename: "./log.txt" });

worker.js

self.onmessage = async (e) => {
  const { filename } = e.data;
  const text = await Deno.readTextFile(filename);
  console.log(text);
  self.close();
};

log.txt

hello world
$ deno run --allow-read --unstable main.js
hello world

Deno名前空間がWorkerスコープで使用可能な場合、Workerは親プロセスのパーミッション(--allow-*フラグを使用して指定されたもの)を継承します。

パーミッションをWorkerに対して構成可能にする予定です。

サードパーティのコードへのリンク

入門」のセクションでは、DenoがURLからスクリプトを実行できることを確認しました。ブラウザのJavaScriptと同様に、DenoはURLから直接ライブラリをインポートできます。この例では、URLを使用してアサーションライブラリをインポートします。

test.ts

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

assertEquals("hello", "hello");
assertEquals("world", "world");

console.log("Asserted! ✓");

これを実行してみてください:

$ deno run test.ts
Compile file:///mnt/f9/Projects/github.com/denoland/deno/docs/test.ts
Download https://deno.land/std@0.65.0/testing/asserts.ts
Download https://deno.land/std@0.65.0/fmt/colors.ts
Download https://deno.land/std@0.65.0/testing/diff.ts
Asserted! ✓

このプログラムに--allow-netフラグを提供する必要はなかったが、ネットワークにアクセスしたことに注意してください。ランタイムには、インポートをダウンロードしてディスクにキャッシュするための特別なアクセス権があります。

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

  • Linux/Redox: $XDG_CACHE_HOME/deno or $HOME/.cache/deno
  • Windows: %LOCALAPPDATA%/deno (%LOCALAPPDATA% = FOLDERID_LocalAppData)
  • macOS: $HOME/Library/Caches/deno
  • 何かが失敗した場合、$HOME/.denoにフォールバックします。

FAQ

モジュールの特定のバージョンをインポートするにはどうすればよいですか?

URLでバージョンを指定します。例えば、次のように実行中のコードで完全URLで指定します。 https://unpkg.com/liltest@0.0.5/dist/liltest.js

どこにでもURLをインポートするのは扱いにくいと思います。

URLの1つが微妙に異なるバージョンのライブラリにリンクしている場合はどうなりますか?
大規模なプロジェクトのどこにでもURLを保持するのは間違いやすいのではないでしょうか?

解決策は、外部のライブラリをdeps.tsファイル(Nodeのpackage.jsonファイルと同じ目的で機能する)にインポートおよび再エクスポートすることです。例えば、大規模なプロジェクト全体で上記のアサーションライブラリを使用していたとしましょう。 "https://deno.land/std@0.65.0/testing/asserts.ts"をどこにでもインポートするのではなく、サードパーティのコードをエクスポートするdeps.tsファイルを作成できます。

deps.ts

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

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

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

この設計により、パッケージ管理ソフトウェア、一元化されたコードリポジトリ、および余分なファイル形式によって生成される大量の複雑さが回避されます。

変更される可能性のあるURLを信頼するにはどうすればよいですか?

ロックファイル(--lockコマンドラインフラグを指定)を使用することで、URLから取得したコードが初期開発時のものと同じであることを確認できます。これについて詳しくは、こちらをご覧ください。

しかし、URLのホストがダウンした場合はどうなりますか?ソースは利用できません。

これは、上記と同様に、リモートの依存関係システムが直面する問題です。外部サーバーに依存することは、開発には便利ですが、本番環境では脆弱です。本番ソフトウェアは、常にその依存関係を提供する必要があります。 Nodeでは、これはnode_modulesをソース管理にチェックインすることで行われます。
Denoでは、実行時に$DENO_DIRをプロジェクトローカルディレクトリにポイントし、同様にそれをソース管理にチェックインすることでこれを行います。

# Download the dependencies.
DENO_DIR=./deno_dir deno cache src/deps.ts

# Make sure the variable is set for any command which invokes the cache.
DENO_DIR=./deno_dir deno test src

# Check the directory into source control.
git add -u deno_dir
git commit

モジュールの再読み込み

デフォルトでは、キャッシュ内のモジュールは、フェッチまたは再コンパイルせずに再利用されます。これは望ましくない場合があり、denoにモジュールを再フェッチしてキャッシュに再コンパイルさせることができます。 deno cacheサブコマンドの--reloadフラグを使用して、ローカルのDENO_DIRキャッシュを無効にすることができます。使い方は以下の通りです:

すべてをリロードする

deno cache --reload my_module.ts

特定のモジュールをリロードする

一部のモジュールのみをアップグレードしたい場合があります。 --reloadフラグに引数を渡すことで制御できます。

全ての 0.65.0 標準モジュールをリロードする:

deno cache --reload=https://deno.land/std@v0.65.0 my_module.ts

特定のモジュール(この例では、色とファイルシステムのコピー)を再ロードするには、コンマを使用してURLを区切ります:

deno cache --reload=https://deno.land/std@0.65.0/fs/copy.ts,https://deno.land/std@0.65.0/fmt/colors.ts my_module.ts

整合性チェックとファイルのロック

イントロダクション

あなたのモジュールがリモートモジュールhttps://some.url/a.tsに依存しているとしましょう。モジュールを初めてコンパイルするとき、a.tsが取得、コンパイル、およびキャッシュされます。これは、新しいマシンでモジュールを実行する(例えば、本番環境で)か、キャッシュを再ロードする(例えば、deno cache --reloadを使用)まで、この方法のままです。しかし、リモートURL https://some.url/a.tsのコンテンツが変更された場合はどうなりますか?これにより、ローカルモジュールとは異なる依存関係コードで運用モジュールが実行される可能性があります。これを回避するためのDenoのソリューションは、整合性チェックとロックファイルを使用することです。

ファイルのキャッシュとロック

Denoは、小さなJSONファイルを使用して、モジュールのサブリソースの整合性を保存およびチェックできます。

--lock=lock.jsonを使用して、ロックファイルのチェックを有効にして指定します。ロックを更新または作成するには、--lock=lock.json --lock-writeを使用します。--lock=lock.jsonはDenoに使用するロックファイルを教えますが、--lock-writeは依存関係ハッシュをロックファイルに出力するために使用されます(--lock-write--lockと組み合わせて使用​​する必要があります) )。

lock.jsonは次のようになり、依存関係に対するファイルのハッシュを保存します。

{
  "https://deno.land/std@v0.65.0/textproto/mod.ts": "3118d7a42c03c242c5a49c2ad91c8396110e14acca1324e7aaefd31a999b71a4",
  "https://deno.land/std@v0.65.0/io/util.ts": "ae133d310a0fdcf298cea7bc09a599c49acb616d34e148e263bcb02976f80dee",
  "https://deno.land/std@v0.65.0/async/delay.ts": "35957d585a6e3dd87706858fb1d6b551cb278271b03f52c5a2cb70e65e00c26a",
   ...
}

一般的なワークフローは次のようになります。:

src/deps.ts

// Add a new dependency to "src/deps.ts", used somewhere else.
export { xyz } from "https://unpkg.com/xyz-lib@v0.9.0/lib.ts";

それから:

# # Create/update the lock file "lock.json".
deno cache --lock=lock.json --lock-write src/deps.ts

# Include it when committing to source control.
git add -u lock.json
git commit -m "feat: Add support for xyz using xyz-lib"
git push

別のマシンのコラボレーター-新しくクローンされたプロジェクトツリー内:

# Download the project's dependencies into the machine's cache, integrity
# checking each resource.
deno cache -reload --lock=lock.json src/deps.ts

# Done! You can proceed safely.
deno test --allow-read src

ランタイム検証

上記のキャッシュと同様に、deno runサブコマンドの使用中に--lock=lock.jsonオプションを使用して、実行中にロックされたモジュールの整合性を検証することもできます。これは、以前にlock.jsonファイルに追加された依存関係に対してのみ検証されることに注意してください。新しい依存関係はキャッシュされますが検証されません。

--cached-onlyフラグを使用してリモート依存関係がすでにキャッシュされていることを要求することで、これをさらに一歩進めることができます。

deno run --lock=lock.json --cached-only mod.ts

まだキャッシュされていないmod.tsの依存関係ツリーに依存関係がある場合、これは失敗します。

プロキシ

Denoは、モジュールダウンロードのプロキシとWeb標準fetchAPIをサポートしています。

プロキシ構成は、環境変数HTTP_PROXYおよびHTTPS_PROXYから読み取られます。

Windowsの場合、環境変数が見つからない場合、Denoはレジストリからプロキシを読み取るようにフォールバックします。

Import maps

これは不安定な機能です。不安定な機能の詳細をご覧ください。

Denoはimport mapsをサポートしています。 --importmap=<FILE>のCLIフラグでimport mapsを使用できます。

現在の制限:

  • 単一のインポートマップ
  • フォールバックURLなし
  • Denostd:名前空間をサポートしていません
  • file:http:https: スキームのみをサポート

例:

import_map.json

{
   "imports": {
      "fmt/": "https://deno.land/std@0.65.0/fmt/"
   }
}

color.ts

import { red } from "fmt/colors.ts";

console.log(red("hello world"));

それから:

$ deno run --importmap=import_map.json --unstable color.ts

ディレクトリを絶対パスでインポートを使用するには:

// import_map.json

{
  "imports": {
    "/": "./"
  }
}
// main.ts

import { MyUtil } from "/util.ts";

別のディレクトリをマッピングすることができます(例:src):

// import_map.json

{
  "imports": {
    "/": "./src"
  }
}

標準ライブラリ

Denoは、コアチームによって監査され、Denoでの動作が保証されている一連の標準モジュールを提供します。

標準ライブラリはhttps://deno.land/std/で入手できます。

バージョン管理と安定性

標準ライブラリはまだ安定していないため、Denoとはバージョンが異なります。最新のリリースについては、https://deno.land/std/またはhttps://deno.land/std/version.ts。を参照してください。標準ライブラリは、Denoがリリースされるたびにリリースされます。

意図しない変更を避けるために、常に標準ライブラリの固定バージョンでインポートを使用することを強くお勧めします。例えば、いつでも変更される可能性があるコードのマスターブランチにリンクするのではなく、コンパイルエラーや予期しない動作を引き起こす可能性があります。

// imports from master, this should be avoided
import { copy } from "https://deno.land/std/fs/copy.ts";

代わりに、バージョンを指定してstdライブラリを使用すればイミュータブルです:

// imports from v0.65.0 of std, never changes
import { copy } from "https://deno.land/std@0.65.0/fs/copy.ts";

トラブルシューティング

標準ライブラリで提供されているモジュールの一部は、不安定なDeno APIを使用しています。

このようなモジュールを--unstable CLIフラグなしで実行しようとすると、Deno名前空間にいくつかのAPIが存在しないことを示唆する多くのTypeScriptエラーが発生します。

// main.ts
import { copy } from "https://deno.land/std@0.65.0/fs/copy.ts";

copy("log.txt", "log-old.txt");
$ deno run --allow-read --allow-write main.ts
Compile file:///dev/deno/main.ts
Download https://deno.land/std@0.65.0/fs/copy.ts
Download https://deno.land/std@0.65.0/fs/ensure_dir.ts
Download https://deno.land/std@0.65.0/fs/_util.ts
error: TS2339 [ERROR]: Property 'utime' does not exist on type 'typeof Deno'.
    await Deno.utime(dest, statInfo.atime, statInfo.mtime);
               ~~~~~
    at https://deno.land/std@0.65.0/fs/copy.ts:90:16

TS2339 [ERROR]: Property 'utimeSync' does not exist on type 'typeof Deno'.
    Deno.utimeSync(dest, statInfo.atime, statInfo.mtime);
         ~~~~~~~~~
    at https://deno.land/std@0.65.0/fs/copy.ts:101:10

この問題を解決するには、--unstableフラグを追加する必要があります:

deno run --allow-read --allow-write --unstable main.ts

API生成エラーが不安定であることを確認するには、 lib.deno.unstable.d.ts を確認してください。

この問題は近い将来に修正される予定です。依存する特定のモジュールがフラグなしで正常にコンパイルされる場合は、フラグを省略してもかまいません。

テスト

Denoには、JavaScriptまたはTypeScriptコードのテストに使用できる組み込みのテストランナーがあります。

テストを書く

テストを定義するには、テストする名前と関数を指定してDeno.testを呼び出す必要があります。

使用できるスタイルは2つあります:

// Simple name and function, compact form, but not configurable
Deno.test("hello world #1", () => {
  const x = 1 + 2;
  assertEquals(x, 3);
});

// Fully fledged test definition, longer form, but configurable (see below)
Deno.test({
  name: "hello world #2",
  fn: () => {
    const x = 1 + 2;
    assertEquals(x, 3);
  },
});

アサーション

テストを容易にするために、https://deno.land/std@0.65.0/testing#usageに有用なアサーションユーティリティがいくつかあります。

import {
  assertEquals,
  assertArrayContains,
} from "https://deno.land/std@0.65.0/testing/asserts.ts";

Deno.test("hello world", () => {
  const x = 1 + 2;
  assertEquals(x, 3);
  assertArrayContains([1, 2, 3, 4, 5, 6], [3], "Expected 3 to be in the array");
});

非同期なファンクション

promiseを返すテスト関数を渡すことで、非同期コードをテストすることもできます。このため、関数を定義するときにasyncキーワードを使用できます:

import { delay } from "https://deno.land/std@0.65.0/async/delay.ts";

Deno.test("async hello world", async () => {
  const x = 1 + 2;

  // await some async task
  await delay(100);

  if (x !== 3) {
    throw Error("x should be equal to 3");
  }
});

リソースおよび非同期なopサニタイザー

Denoの特定のアクションは、リソーステーブルにリソースを作成します(詳細はこちら)。これらのリソースは、使い終わったら閉じてください。

各テスト定義について、テストランナーはこのテストで作成されたすべてのリソースが閉じられていることを確認します。これは、リソースの「リーク」を防ぐためです。これはすべてのテストでデフォルトで有効になっていますが、テスト定義でsanitizeResourcesのboolean値をfalseに設定することで無効にできます。

ファイルシステムとの対話などの非同期操作についても同様です。テストランナーは、テストで開始する各操作がテストの終了前に完了することを確認します。これはすべてのテストでデフォルトで有効になっていますが、テスト定義でsanitizeOpsのboolean値をfalseに設定することで無効にできます。

Deno.test({
  name: "leaky test",
  fn() {
    Deno.open("hello.txt");
  },
  sanitizeResources: false,
  sanitizeOps: false,
});

テストの実行

テストを実行するには、テスト関数を含むファイルを使用してdeno testを呼び出します。また、ファイル名を省略することもできます。その場合、現在のディレクトリ内でglobが{*_,*.,}test.{js,mjs,ts,jsx,tsx}に一致するすべてのテストが(再帰的に)実行されます。ディレクトリを渡すと、このglobに一致するディレクトリ内のすべてのファイルが実行されます。

# Run all tests in the current directly and all sub-directories
deno test

# Run all tests in the util directory
deno test util/

# Run just my_test.ts
deno test my_test.ts

deno testdeno runと同じアクセス許可モデルを使用するため、例えば、テスト中に--allow-writeを実行してファイルシステムに書き込む必要があります。

deno testのすべてのランタイムオプションを表示するには、コマンドラインのhelpで参照できます。

deno help test

フィルタリング

実行中のテストをフィルタリングするためのオプションがいくつかあります。

コマンドラインでフィルタリングする

テストは、コマンドラインの--filterオプションを使用して、個別にまたはグループで実行できます。

フィルターフラグは、文字列またはパターンを値として受け入れます。

次のテストを想定しています。

Deno.test({ name: "my-test", fn: myTest });
Deno.test({ name: "test-1", fn: test1 });
Deno.test({ name: "test2", fn: test2 });

これらのテストにはすべて「test」という単語が含まれているため、このコマンドはこれらのテストをすべて実行します。

deno test --filter "test" tests/

反対に、次のコマンドはパターンを使用して、2番目と3番目のテストを実行します:

deno test --filter "/test-*\d/" tests/

パターンを使用することをDenoに通知するには、REGEXのJavaScript構文シュガーのように、フィルターをスラッシュで囲みます。

テスト定義のフィルタリング

テスト自体には、フィルタリングのための2つのオプションがあります。

フィルタリング(特定のテストは無視)

ある種の条件に基づくテストを無視したい場合があります(例えば、Windowsでのみテストを実行したい場合など)。このために、テスト定義でignoreのboolean値を使用できます。 trueに設定されている場合、テストはスキップされます。

Deno.test({
  name: "do macOS feature",
  ignore: Deno.build.os !== "darwin",
  fn() {
    doMacOSFeature();
  },
});

フィルタリング(特定のテストのみを実行)

大きなテストクラス内で問題の真っ只中にいる可能性があり、そのテストのみに焦点を当て、残りは今は無視したい場合があります。このため、onlyのオプションを使用して、テストフレームワークに、trueに設定されたテストのみを実行するように指示できます。複数のテストでこのオプションを設定できます。テストの実行では各テストの成功または失敗が報告されますが、テストでonlyフラグが立てられている場合は、テスト全体が常に失敗します。これは、ほとんどすべてのテストを無効にする一時的な対策に過ぎないためです。

Deno.test({
  name: "Focus on this test only",
  only: true,
  fn() {
    testComplicatedStuff();
  },
});

失敗を早める

長時間実行するテストスイートがあり、最初の失敗時にテストスイートを停止したい場合は、スイートの実行時に--failfastフラグを指定できます。

deno test --failfast

アサーション

開発者がテストを記述できるように、Deno標準ライブラリには、 https://deno.land/std@0.65.0/testing/asserts.tsからインポートできる組み込みのアサーションモジュールが付属しています。

import { assert } from "https://deno.land/std@0.65.0/testing/asserts.ts";

Deno.test("Hello Test", () => {
  assert("Hello");
});

アサーションモジュールは、9つのアサーションを提供します:

  • assert(expr: unknown, msg = ""): asserts expr
  • assertEquals(actual: unknown, expected: unknown, msg?: string): void
  • assertNotEquals(actual: unknown, expected: unknown, msg?: string): void
  • assertStrictEquals(actual: unknown, expected: unknown, msg?: string): void
  • assertStringContains(actual: string, expected: string, msg?: string): void
  • assertArrayContains(actual: unknown[], expected: unknown[], msg?: string): void
  • assertMatch(actual: string, expected: RegExp, msg?: string): void
  • assertThrows(fn: () => void, ErrorClass?: Constructor, msgIncludes = "", msg?: string): Error
  • assertThrowsAsync(fn: () => Promise<void>, ErrorClass?: Constructor, msgIncludes = "", msg?: string): Promise<Error>

アサート

assertメソッドは単純な「真の」アサーションであり、trueと推定できる任意の値をアサートするために使用できます。

Deno.test("Test Assert", () => {
  assert(1);
  assert("Hello");
  assert(true);
});

等価性

利用可能な等価アサーションには、assertEquals()assertNotEquals()assertStrictEquals()の3つがあります

assertEquals()assertNotEquals() のメソッドは、一般的な等価チェックを提供し、プリミティブ型とオブジェクト間の等価をアサートすることができます。

Deno.test("Test Assert Equals", () => {
  assertEquals(1, 1);
  assertEquals("Hello", "Hello");
  assertEquals(true, true);
  assertEquals(undefined, undefined);
  assertEquals(null, null);
  assertEquals(new Date(), new Date());
  assertEquals(new RegExp("abc"), new RegExp("abc"));

  class Foo {}
  const foo1 = new Foo();
  const foo2 = new Foo();

  assertEquals(foo1, foo2);
});

Deno.test("Test Assert Not Equals", () => {
  assertNotEquals(1, 2);
  assertNotEquals("Hello", "World");
  assertNotEquals(true, false);
  assertNotEquals(undefined, "");
  assertNotEquals(new Date(), Date.now());
  assertNotEquals(new RegExp("abc"), new RegExp("def"));
});

対照的に、assertStrictEquals()は、===演算子に基づいて、より単純で厳密な等価チェックを提供します。結果として、同一オブジェクトの2つのインスタンスは参照上同じではないため、アサートされません。

Deno.test("Test Assert Strict Equals", () => {
  assertStrictEquals(1, 1);
  assertStrictEquals("Hello", "Hello");
  assertStrictEquals(true, true);
  assertStrictEquals(undefined, undefined);
});

assertStrictEquals()アサーションは、2つのプリミティブ型を正確にチェックする場合に最適です。

包含

値が値を含むことをアサートするために使用できるメソッドは、assertStringContains()assertArrayContains()の2つです。

assertStringContains()アサーションは、対象の文字列に対して、単純に期待される文字列が含まれているかどうかを調べます。

Deno.test("Test Assert String Contains", () => {
  assertStringContains("Hello World", "Hello");
});

assertArrayContains()アサーションは少し高度で、配列内の値と配列内の値の配列の両方を見つけることができます。

Deno.test("Test Assert Array Contains", () => {
  assertArrayContains([1, 2, 3], [1]);
  assertArrayContains([1, 2, 3], [1, 2]);
  assertArrayContains(Array.from("Hello World"), Array.from("Hello"));
});

Regex

assertMatch() を介して正規表現をアサートできます。

Deno.test("Test Assert Match", () => {
  assertMatch("abcdefghi", new RegExp("def"));

  const basicUrl = new RegExp("^https?://[a-z.]+.com$");
  assertMatch("https://www.google.com", basicUrl);
  assertMatch("http://facebook.com", basicUrl);
});

エラーのスロー

Denoでエラーがスローされたかどうかをアサートするには、assertThrows()assertAsyncThrows()の2つの方法があります。どちらのアサーションでも、Errorがスローされたこと、スローされたエラーのタイプ、メッセージが何であったかを確認できます。

2つのアサーションの違いは、assertThrows()が標準関数を受け入れ、assertAsyncThrows()Promise を返す関数を受け入れることです。

assertThrows()は、エラーがスローされたことを確認し、オプションで、スローされたエラーが正しいタイプであることを確認し、エラーメッセージが期待どおりであることをアサートします。

Deno.test("Test Assert Throws", () => {
  assertThrows(
    () => {
      throw new Error("Panic!");
    },
    Error,
    "Panic!",
  );
});

assertAsyncThrows() は、主にPromiseを処理するため、もう少し複雑です。しかし、基本的にはPromiseでスローされたエラーや拒否をキャッチします。オプションで、エラーの種類とエラーメッセージを確認することもできます。

Deno.test("Test Assert Throws Async", () => {
  assertThrowsAsync(
    () => {
      return new Promise(() => {
        throw new Error("Panic! Threw Error");
      });
    },
    Error,
    "Panic! Threw Error",
  );

  assertThrowsAsync(
    () => {
      return Promise.reject(new Error("Panic! Reject Error"));
    },
    Error,
    "Panic! Reject Error",
  );
});

カスタムメッセージ

Denoの組み込みアサーションはそれぞれ、必要に応じて標準のCLIエラーメッセージを上書きできます。

例えば、この例では標準のCLIエラーメッセージではなく、"Values Don't Match!"が出力されます。

Deno.test("Test Assert Equal Fail Custom Message", () => {
  assertEquals(1, 2, "Values Don't Match!");
});

ビルトインツール

Denoは、JavaScriptおよびTypeScriptを操作するときに役立つ組み込みツールをいくつか提供しています。

Debugger

Deno supports the V8 Inspector Protocol.

It's possible to debug Deno programs using Chrome Devtools or other clients that support the protocol (eg. VSCode).

To activate debugging capabilities run Deno with the --inspect or --inspect-brk flags.

The --inspect flag allows attaching the debugger at any point in time, while --inspect-brk will wait for the debugger to attach and will pause execution on the first line of code.

Chrome Devtools

Let's try debugging a program using Chrome Devtools. For this, we'll use file_server.ts from std, a static file server.

Use the --inspect-brk flag to break execution on the first line:

$ deno run --inspect-brk --allow-read --allow-net https://deno.land/std@v0.65.0/http/file_server.ts
Debugger listening on ws://127.0.0.1:9229/ws/1e82c406-85a9-44ab-86b6-7341583480b1
Download https://deno.land/std@v0.65.0/http/file_server.ts
Compile https://deno.land/std@v0.65.0/http/file_server.ts
...

Open chrome://inspect and click Inspect next to target:

chrome://inspect

It might take a few seconds after opening the devtools to load all modules.

Devtools opened

You might notice that Devtools paused execution on the first line of _constants.ts instead of file_server.ts. This is expected behavior and is caused by the way ES modules are evaluated by V8 (_constants.ts is left-most, bottom-most dependency of file_server.ts so it is evaluated first).

At this point all source code is available in the Devtools, so let's open up file_server.ts and add a breakpoint there; go to "Sources" pane and expand the tree:

Open file_server.ts

Looking closely you'll find duplicate entries for each file; one written regularly and one in italics. The former is compiled source file (so in the case of .ts files it will be emitted JavaScript source), while the latter is a source map for the file.

Next, add a breakpoint in the listenAndServe method:

Break in file_server.ts

As soon as we've added the breakpoint Devtools automatically opened up the source map file, which allows us step through the actual source code that includes types.

Now that we have our breakpoints set, we can resume the execution of our script so that we might inspect an incoming request. Hit the Resume script execution button to do so. You might even need to hit it twice!

Once our script is running again, let's send a request and inspect it in Devtools:

$ curl http://0.0.0.0:4500/

Break in request handling

At this point we can introspect the contents of the request and go step-by-step to debug the code.

VSCode

Deno can be debugged using VSCode.

Official support via the plugin is being worked on - https://github.com/denoland/vscode_deno/issues/12

We can still attach the debugger by manually providing a launch.json config:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Deno",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "deno",
      "runtimeArgs": ["run", "--inspect-brk", "-A", "${file}"],
      "port": 9229
    }
  ]
}

NOTE: This uses the file you have open as the entry point; replace ${file} with a script name if you want a fixed entry point.

Let's try out debugging a local source file. Create server.ts:

import { serve } from "https://deno.land/std@v0.65.0/http/server.ts";
const server = serve({ port: 8000 });
console.log("http://localhost:8000/");

for await (const req of server) {
  req.respond({ body: "Hello World\n" });
}

Then we can set a breakpoint, and run the created configuration:

VSCode debugger

JetBrains IDEs

You can debug Deno using your JetBrains IDE by right-clicking the file you want to debug and selecting the Debug 'Deno: <file name>' option. This will create a run/debug configuration with no permission flags set. To configure these flags edit the run/debug configuration and modify the Arguments field with the required flags.

Other

Any client that implements the Devtools protocol should be able to connect to a Deno process.

Limitations

Devtools support is still immature. There is some functionality that is known to be missing or buggy:

  • autocomplete in Devtools' console causes the Deno process to exit
  • profiling and memory dumps might not work correctly

Script installer

Deno provides deno install to easily install and distribute executable code.

deno install [OPTIONS...] [URL] [SCRIPT_ARGS...] will install the script available at URL under the name EXE_NAME.

This command creates a thin, executable shell script which invokes deno using the specified CLI flags and main module. It is placed in the installation root's bin directory.

Example:

$ 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

To change the executable name, use -n/--name:

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

The executable name is inferred by default:

  • Attempt to take the file stem of the URL path. The above example would become '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.

To change the installation root, use --root:

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

The installation root is determined, in order of precedence:

  • --root option
  • DENO_INSTALL_ROOT environment variable
  • $HOME/.deno

These must be added to the path manually if required.

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

You must specify permissions that will be used to run the script at installation time.

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

The above command creates an executable called file_server that runs with network and read permissions and binds to port 8080.

For good practice, use the import.meta.main idiom to specify the entry point in an executable script.

Example:

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

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

When you create an executable script make sure to let users know by adding an example installation command to your repository:

# Install using deno install

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

Code formatter

Deno ships with a built in code formatter that auto-formats TypeScript and JavaScript code.

# format all JS/TS files in the current directory and subdirectories
deno fmt
# format specific files
deno fmt myfile1.ts myfile2.ts
# check if all the JS/TS files in the current directory and subdirectories are formatted
deno fmt --check
# format stdin and write to stdout
cat file.ts | deno fmt -

Ignore formatting code by preceding it with a // deno-fmt-ignore comment:

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

Or ignore an entire file by adding a // deno-fmt-ignore-file comment at the top of the file.

Bundling

deno bundle [URL] will output a single JavaScript file, which includes all dependencies of the specified input. For example:

> 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.

If you omit the out file, the bundle will be sent to stdout.

The bundle can just be run as any other module in Deno would:

deno run colors.bundle.js

The output is a self contained ES Module, where any exports from the main module supplied on the command line will be available. For example, if the main module looked something like this:

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

export const bar = "bar";

It could be imported like this:

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

Bundles can also be loaded in the web browser. The bundle is a self-contained ES module, and so the attribute of type must be set to "module". For example:

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

Or you could import it into another ES module to consume:

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

Documentation Generator

deno doc followed by a list of one or more source files will print the JSDoc documentation for each of the module's exported members. Currently, only exports in the style export <declaration> and export ... from ... are supported.

For example, given a file add.ts with the contents:

/**
 * Adds x and y.
 * @param {number} x
 * @param {number} y
 * @returns {number} Sum of x and y
 */
export function add(x: number, y: number): number {
  return x + y;
}

Running the Deno doc command, prints the function's JSDoc comment to stdout:

deno doc add.ts
function add(x: number, y: number): number
  Adds x and y. @param {number} x @param {number} y @returns {number} Sum of x and y

Use the --json flag to output the documentation in JSON format. This JSON format is consumed by the deno doc website and used to generate module documentation.

Dependency Inspector

deno info [URL] will inspect ES module and all of its dependencies.

deno info https://deno.land/std@0.52.0/http/file_server.ts
Download https://deno.land/std@0.52.0/http/file_server.ts
...
local: /Users/deno/Library/Caches/deno/deps/https/deno.land/5bd138988e9d20db1a436666628ffb3f7586934e0a2a9fe2a7b7bf4fb7f70b98
type: TypeScript
compiled: /Users/deno/Library/Caches/deno/gen/https/deno.land/std@0.52.0/http/file_server.ts.js
map: /Users/deno/Library/Caches/deno/gen/https/deno.land/std@0.52.0/http/file_server.ts.js.map
deps:
https://deno.land/std@0.52.0/http/file_server.ts
  ├─┬ https://deno.land/std@0.52.0/path/mod.ts
  │ ├─┬ https://deno.land/std@0.52.0/path/win32.ts
  │ │ ├── https://deno.land/std@0.52.0/path/_constants.ts
  │ │ ├─┬ https://deno.land/std@0.52.0/path/_util.ts
  │ │ │ └── https://deno.land/std@0.52.0/path/_constants.ts
  │ │ └─┬ https://deno.land/std@0.52.0/testing/asserts.ts
  │ │   ├── https://deno.land/std@0.52.0/fmt/colors.ts
  │ │   └── https://deno.land/std@0.52.0/testing/diff.ts
  │ ├─┬ https://deno.land/std@0.52.0/path/posix.ts
  │ │ ├── https://deno.land/std@0.52.0/path/_constants.ts
  │ │ └── https://deno.land/std@0.52.0/path/_util.ts
  │ ├─┬ https://deno.land/std@0.52.0/path/common.ts
  │ │ └── https://deno.land/std@0.52.0/path/separator.ts
  │ ├── https://deno.land/std@0.52.0/path/separator.ts
  │ ├── https://deno.land/std@0.52.0/path/interface.ts
  │ └─┬ https://deno.land/std@0.52.0/path/glob.ts
  │   ├── https://deno.land/std@0.52.0/path/separator.ts
  │   ├── https://deno.land/std@0.52.0/path/_globrex.ts
  │   ├── https://deno.land/std@0.52.0/path/mod.ts
  │   └── https://deno.land/std@0.52.0/testing/asserts.ts
  ├─┬ https://deno.land/std@0.52.0/http/server.ts
  │ ├── https://deno.land/std@0.52.0/encoding/utf8.ts
  │ ├─┬ https://deno.land/std@0.52.0/io/bufio.ts
  │ │ ├─┬ https://deno.land/std@0.52.0/io/util.ts
  │ │ │ ├── https://deno.land/std@0.52.0/path/mod.ts
  │ │ │ └── https://deno.land/std@0.52.0/encoding/utf8.ts
  │ │ └── https://deno.land/std@0.52.0/testing/asserts.ts
  │ ├── https://deno.land/std@0.52.0/testing/asserts.ts
  │ ├─┬ https://deno.land/std@0.52.0/async/mod.ts
  │ │ ├── https://deno.land/std@0.52.0/async/deferred.ts
  │ │ ├── https://deno.land/std@0.52.0/async/delay.ts
  │ │ └─┬ https://deno.land/std@0.52.0/async/mux_async_iterator.ts
  │ │   └── https://deno.land/std@0.52.0/async/deferred.ts
  │ └─┬ https://deno.land/std@0.52.0/http/_io.ts
  │   ├── https://deno.land/std@0.52.0/io/bufio.ts
  │   ├─┬ https://deno.land/std@0.52.0/textproto/mod.ts
  │   │ ├── https://deno.land/std@0.52.0/io/util.ts
  │   │ ├─┬ https://deno.land/std@0.52.0/bytes/mod.ts
  │   │ │ └── https://deno.land/std@0.52.0/io/util.ts
  │   │ └── https://deno.land/std@0.52.0/encoding/utf8.ts
  │   ├── https://deno.land/std@0.52.0/testing/asserts.ts
  │   ├── https://deno.land/std@0.52.0/encoding/utf8.ts
  │   ├── https://deno.land/std@0.52.0/http/server.ts
  │   └── https://deno.land/std@0.52.0/http/http_status.ts
  ├─┬ https://deno.land/std@0.52.0/flags/mod.ts
  │ └── https://deno.land/std@0.52.0/testing/asserts.ts
  └── https://deno.land/std@0.52.0/testing/asserts.ts

Dependency inspector works with any local or remote ES modules.

Cache location

deno info can be used to display information about cache location:

deno info
DENO_DIR location: "/Users/deno/Library/Caches/deno"
Remote modules cache: "/Users/deno/Library/Caches/deno/deps"
TypeScript compiler cache: "/Users/deno/Library/Caches/deno/gen"

Linter

Deno ships with a built in code linter for JavaScript and TypeScript.

Note: linter is a new feature and still unstable thus it requires --unstable flag

# lint all JS/TS files in the current directory and subdirectories
deno lint --unstable
# lint specific files
deno lint --unstable myfile1.ts myfile2.ts

Available rules

  • ban-ts-comment
  • ban-untagged-ignore
  • constructor-super
  • for-direction
  • getter-return
  • no-array-constructor
  • no-async-promise-executor
  • no-case-declarations
  • no-class-assign
  • no-compare-neg-zero
  • no-cond-assign
  • no-debugger
  • no-delete-var
  • no-dupe-args
  • no-dupe-keys
  • no-duplicate-case
  • no-empty-character-class
  • no-empty-interface
  • no-empty-pattern
  • no-empty
  • no-ex-assign
  • no-explicit-any
  • no-func-assign
  • no-misused-new
  • no-namespace
  • no-new-symbol
  • no-obj-call
  • no-octal
  • no-prototype-builtins
  • no-regex-spaces
  • no-setter-return
  • no-this-alias
  • no-this-before-super
  • no-unsafe-finally
  • no-unsafe-negation
  • no-with
  • prefer-as-const
  • prefer-namespace-keyword
  • require-yield
  • triple-slash-reference
  • use-isnan
  • valid-typeof

Ignore directives

Files

To ignore whole file // deno-lint-ignore-file directive should placed at the top of the file.

// deno-lint-ignore-file

function foo(): any {
  // ...
}

Ignore directive must be placed before first stament or declaration:

// Copyright 2020 the Deno authors. All rights reserved. MIT license.

/**
 * Some JS doc
 **/

// deno-lint-ignore-file

import { bar } from "./bar.js";

function foo(): any {
  // ...
}

Diagnostics

To ignore certain diagnostic // deno-lint-ignore <codes...> directive should be placed before offending line. Specifying ignored rule name is required.

// deno-lint-ignore no-explicit-any
function foo(): any {
  // ...
}

// deno-lint-ignore no-explicit-any explicit-function-return-type
function bar(a: any) {
  // ...
}

To provide some compatibility with ESLint deno lint also supports // eslint-ignore-next-line directive. Just like in // deno-lint-ignore it's required to specify ignored rule name is required.

// eslint-ignore-next-line no-empty
while (true) {}

// eslint-ignore-next-line @typescript-eslint/no-explicit-any
function bar(a: any) {
  // ...
}

組み込みDeno

Denoは複数の部分で構成されており、そのうちの1つはdeno_coreです。これは、JavaScriptランタイムをRustアプリケーションに埋め込むために使用できるRust Crateです。 Denoはdeno_coreの上に構築されています。

Denoクレートは、crates.ioでホストされています。

APIはdocs.rsで確認できます。

Contributing

  • Read the style guide.

  • Please don't make the benchmarks worse.

  • Ask for help in the community chat room.

  • If you are going to work on an issue, mention so in the issue comments before you start working on the issue.

  • Please be professional in the forums. We follow Rust's code of conduct (CoC) Have a problem? Email ry@tinyclouds.org.

Development

Instructions on how to build from source can be found here.

Submitting a Pull Request

Before submitting, please make sure the following is done:

  1. That there is a related issue and it is referenced in the PR text.
  2. There are tests that cover the changes.
  3. Ensure cargo test passes.
  4. Format your code with ./tools/format.py
  5. Make sure ./tools/lint.py passes.

Changes to third_party

deno_third_party contains most of the external code that Deno depends on, so that we know exactly what we are executing at any given time. It is carefully maintained with a mixture of manual labor and private scripts. It's likely you will need help from @ry or @piscisaureus to make changes.

Adding Ops (aka bindings)

We are very concerned about making mistakes when adding new APIs. When adding an Op to Deno, the counterpart interfaces on other platforms should be researched. Please list how this functionality is done in Go, Node, Rust, and Python.

As an example, see how Deno.rename() was proposed and added in PR #671.

Releases

Summary of the changes from previous releases can be found here.

Documenting APIs

It is important to document public APIs and we want to do that inline with the code. This helps ensure that code and documentation are tightly coupled together.

Utilize JSDoc

All publicly exposed APIs and types, both via the deno module as well as the global/window namespace should have JSDoc documentation. This documentation is parsed and available to the TypeScript compiler, and therefore easy to provide further downstream. JSDoc blocks come just prior to the statement they apply to and are denoted by a leading /** before terminating with a */. For example:

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

Find more at https://jsdoc.app/

Building from source

Below are instructions on how to build Deno from source. If you just want to use Deno you can download a prebuilt executable (more information in the Getting Started chapter).

Cloning the Repository

Clone on Linux or Mac:

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

Extra steps for Windows users:

  1. Enable "Developer Mode" (otherwise symlinks would require administrator privileges).
  2. Make sure you are using git version 2.19.2.windows.1 or newer.
  3. Set core.symlinks=true before the checkout:
    git config --global core.symlinks true
    git clone --recurse-submodules https://github.com/denoland/deno.git
    

Prerequisites

You will need to install Rust. Make sure to fetch the latest stable release as Deno does not support nightly builds. Check that you have the required tools:

rustc -V
cargo -V

Setup rust targets and components

rustup target add wasm32-unknown-unknown
rustup target add wasm32-wasi

Building Deno

The easiest way to build Deno is by using a precompiled version of V8:

cargo build -vv

However if you want to build Deno and V8 from source code:

V8_FROM_SOURCE=1 cargo build -vv

When building V8 from source, there are more dependencies:

Python 2. Ensure that a suffix-less python/python.exe exists in your PATH and it refers to Python 2, not 3.

For Linux users glib-2.0 development files must also be installed. (On Ubuntu, run apt install libglib2.0-dev.)

Mac users must have Command Line Tools installed. (XCode already includes CLT. Run xcode-select --install to install it without XCode.)

For Windows users:

  1. Get VS Community 2019 with "Desktop development with C++" toolkit and make sure to select the following required tools listed below along with all C++ tools.

    • 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. Enable "Debugging Tools for Windows". Go to "Control Panel" → "Programs" → "Programs and Features" → Select "Windows Software Development Kit - Windows 10" → "Change" → "Change" → Check "Debugging Tools For Windows" → "Change" -> "Finish". Or use: Debugging Tools for Windows (Notice: it will download the files, you should install X64 Debuggers And Tools-x64_en-us.msi file manually.)

See rusty_v8's README for more details about the V8 build.

Building

Build with Cargo:

# Build:
cargo build -vv

# Build errors?  Ensure you have latest master and try building again, or if that doesn't work try:
cargo clean && cargo build -vv

# Run:
./target/debug/deno run cli/tests/002_hello.ts

Testing and Tools

Tests

Test deno:

# Run the whole suite:
cargo test

# Only test cli/js/:
cargo test js_unit_tests

Test std/:

cargo test std_tests

Lint and format

Lint the code:

./tools/lint.py

Format the code:

./tools/format.py

Profiling

To start profiling,

# 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 tests/http_bench.ts --allow-net --v8-flags=--prof &

# 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:

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:

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:

Debugging with LLDB

To debug the deno binary, we can use rust-lldb. It should come with rustc and is a wrapper around LLDB.

$ 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

V8 flags

V8 has many many internal command-line flags.

$ deno run --v8-flags=--help _
SSE3=1 SSSE3=1 SSE4_1=1 SSE4_2=1 SAHF=1 AVX=1 FMA3=1 BMI1=1 BMI2=1 LZCNT=1 POPCNT=1 ATOM=0
Synopsis:
  shell [options] [--shell] [<file>...]
  d8 [options] [-e <string>] [--shell] [[--module] <file>...]

  -e        execute a string in V8
  --shell   run an interactive JavaScript shell
  --module  execute a file as a JavaScript module

Note: the --module option is implicitly enabled for *.mjs files.

The following syntax for options is accepted (both '-' and '--' are ok):
  --flag        (bool flags only)
  --no-flag     (bool flags only)
  --flag=value  (non-bool flags only, no spaces around '=')
  --flag value  (non-bool flags only)
  --            (captures all remaining args in JavaScript)

Options:
  --use-strict (enforce strict mode)
        type: bool  default: false
  --es-staging (enable test-worthy harmony features (for internal use only))
        type: bool  default: false
  --harmony (enable all completed harmony features)
        type: bool  default: false
  --harmony-shipping (enable all shipped harmony features)
        type: bool  default: true
  --harmony-regexp-sequence (enable "RegExp Unicode sequence properties" (in progress))
        type: bool  default: false
  --harmony-weak-refs-with-cleanup-some (enable "harmony weak references with FinalizationRegistry.prototype.cleanupSome" (in progress))
        type: bool  default: false
  --harmony-regexp-match-indices (enable "harmony regexp match indices" (in progress))
        type: bool  default: false
  --harmony-top-level-await (enable "harmony top level await")
        type: bool  default: false
  --harmony-namespace-exports (enable "harmony namespace exports (export * as foo from 'bar')")
        type: bool  default: true
  --harmony-sharedarraybuffer (enable "harmony sharedarraybuffer")
        type: bool  default: true
  --harmony-import-meta (enable "harmony import.meta property")
        type: bool  default: true
  --harmony-dynamic-import (enable "harmony dynamic import")
        type: bool  default: true
  --harmony-promise-all-settled (enable "harmony Promise.allSettled")
        type: bool  default: true
  --harmony-promise-any (enable "harmony Promise.any")
        type: bool  default: true
  --harmony-private-methods (enable "harmony private methods in class literals")
        type: bool  default: true
  --harmony-weak-refs (enable "harmony weak references")
        type: bool  default: true
  --harmony-string-replaceall (enable "harmony String.prototype.replaceAll")
        type: bool  default: true
  --harmony-logical-assignment (enable "harmony logical assignment")
        type: bool  default: true
  --lite-mode (enables trade-off of performance for memory savings)
        type: bool  default: false
  --future (Implies all staged features that we want to ship in the not-too-far future)
        type: bool  default: false
  --assert-types (generate runtime type assertions to test the typer)
        type: bool  default: false
  --allocation-site-pretenuring (pretenure with allocation sites)
        type: bool  default: true
  --page-promotion (promote pages based on utilization)
        type: bool  default: true
  --always-promote-young-mc (always promote young objects during mark-compact)
        type: bool  default: true
  --page-promotion-threshold (min percentage of live bytes on a page to enable fast evacuation)
        type: int  default: 70
  --trace-pretenuring (trace pretenuring decisions of HAllocate instructions)
        type: bool  default: false
  --trace-pretenuring-statistics (trace allocation site pretenuring statistics)
        type: bool  default: false
  --track-fields (track fields with only smi values)
        type: bool  default: true
  --track-double-fields (track fields with double values)
        type: bool  default: true
  --track-heap-object-fields (track fields with heap values)
        type: bool  default: true
  --track-computed-fields (track computed boilerplate fields)
        type: bool  default: true
  --track-field-types (track field types)
        type: bool  default: true
  --trace-block-coverage (trace collected block coverage information)
        type: bool  default: false
  --trace-protector-invalidation (trace protector cell invalidations)
        type: bool  default: false
  --feedback-normalization (feed back normalization to constructors)
        type: bool  default: false
  --enable-one-shot-optimization (Enable size optimizations for the code that will only be executed once)
        type: bool  default: false
  --unbox-double-arrays (automatically unbox arrays of doubles)
        type: bool  default: true
  --interrupt-budget (interrupt budget which should be used for the profiler counter)
        type: int  default: 147456
  --jitless (Disable runtime allocation of executable memory.)
        type: bool  default: false
  --use-ic (use inline caching)
        type: bool  default: true
  --budget-for-feedback-vector-allocation (The budget in amount of bytecode executed by a function before we decide to allocate feedback vectors)
        type: int  default: 1024
  --lazy-feedback-allocation (Allocate feedback vectors lazily)
        type: bool  default: true
  --ignition-elide-noneffectful-bytecodes (elide bytecodes which won't have any external effect)
        type: bool  default: true
  --ignition-reo (use ignition register equivalence optimizer)
        type: bool  default: true
  --ignition-filter-expression-positions (filter expression positions before the bytecode pipeline)
        type: bool  default: true
  --ignition-share-named-property-feedback (share feedback slots when loading the same named property from the same object)
        type: bool  default: true
  --print-bytecode (print bytecode generated by ignition interpreter)
        type: bool  default: false
  --enable-lazy-source-positions (skip generating source positions during initial compile but regenerate when actually required)
        type: bool  default: true
  --stress-lazy-source-positions (collect lazy source positions immediately after lazy compile)
        type: bool  default: false
  --print-bytecode-filter (filter for selecting which functions to print bytecode)
        type: string  default: *
  --trace-ignition-codegen (trace the codegen of ignition interpreter bytecode handlers)
        type: bool  default: false
  --trace-ignition-dispatches (traces the dispatches to bytecode handlers by the ignition interpreter)
        type: bool  default: false
  --trace-ignition-dispatches-output-file (the file to which the bytecode handler dispatch table is written (by default, the table is not written to a file))
        type: string  default: nullptr
  --fast-math (faster (but maybe less accurate) math functions)
        type: bool  default: true
  --trace-track-allocation-sites (trace the tracking of allocation sites)
        type: bool  default: false
  --trace-migration (trace object migration)
        type: bool  default: false
  --trace-generalization (trace map generalization)
        type: bool  default: false
  --turboprop (enable experimental turboprop mid-tier compiler.)
        type: bool  default: false
  --concurrent-recompilation (optimizing hot functions asynchronously on a separate thread)
        type: bool  default: true
  --trace-concurrent-recompilation (track concurrent recompilation)
        type: bool  default: false
  --concurrent-recompilation-queue-length (the length of the concurrent compilation queue)
        type: int  default: 8
  --concurrent-recompilation-delay (artificial compilation delay in ms)
        type: int  default: 0
  --block-concurrent-recompilation (block queued jobs until released)
        type: bool  default: false
  --concurrent-inlining (run optimizing compiler's inlining phase on a separate thread)
        type: bool  default: false
  --max-serializer-nesting (maximum levels for nesting child serializers)
        type: int  default: 25
  --trace-heap-broker-verbose (trace the heap broker verbosely (all reports))
        type: bool  default: false
  --trace-heap-broker-memory (trace the heap broker memory (refs analysis and zone numbers))
        type: bool  default: false
  --trace-heap-broker (trace the heap broker (reports on missing data only))
        type: bool  default: false
  --stress-runs (number of stress runs)
        type: int  default: 0
  --deopt-every-n-times (deoptimize every n times a deopt point is passed)
        type: int  default: 0
  --print-deopt-stress (print number of possible deopt points)
        type: bool  default: false
  --opt (use adaptive optimizations)
        type: bool  default: true
  --turbo-sp-frame-access (use stack pointer-relative access to frame wherever possible)
        type: bool  default: false
  --turbo-control-flow-aware-allocation (consider control flow while allocating registers)
        type: bool  default: true
  --turbo-filter (optimization filter for TurboFan compiler)
        type: string  default: *
  --trace-turbo (trace generated TurboFan IR)
        type: bool  default: false
  --trace-turbo-path (directory to dump generated TurboFan IR to)
        type: string  default: nullptr
  --trace-turbo-filter (filter for tracing turbofan compilation)
        type: string  default: *
  --trace-turbo-graph (trace generated TurboFan graphs)
        type: bool  default: false
  --trace-turbo-scheduled (trace TurboFan IR with schedule)
        type: bool  default: false
  --trace-turbo-cfg-file (trace turbo cfg graph (for C1 visualizer) to a given file name)
        type: string  default: nullptr
  --trace-turbo-types (trace TurboFan's types)
        type: bool  default: true
  --trace-turbo-scheduler (trace TurboFan's scheduler)
        type: bool  default: false
  --trace-turbo-reduction (trace TurboFan's various reducers)
        type: bool  default: false
  --trace-turbo-trimming (trace TurboFan's graph trimmer)
        type: bool  default: false
  --trace-turbo-jt (trace TurboFan's jump threading)
        type: bool  default: false
  --trace-turbo-ceq (trace TurboFan's control equivalence)
        type: bool  default: false
  --trace-turbo-loop (trace TurboFan's loop optimizations)
        type: bool  default: false
  --trace-turbo-alloc (trace TurboFan's register allocator)
        type: bool  default: false
  --trace-all-uses (trace all use positions)
        type: bool  default: false
  --trace-representation (trace representation types)
        type: bool  default: false
  --turbo-verify (verify TurboFan graphs at each phase)
        type: bool  default: false
  --turbo-verify-machine-graph (verify TurboFan machine graph before instruction selection)
        type: string  default: nullptr
  --trace-verify-csa (trace code stubs verification)
        type: bool  default: false
  --csa-trap-on-node (trigger break point when a node with given id is created in given stub. The format is: StubName,NodeId)
        type: string  default: nullptr
  --turbo-stats (print TurboFan statistics)
        type: bool  default: false
  --turbo-stats-nvp (print TurboFan statistics in machine-readable format)
        type: bool  default: false
  --turbo-stats-wasm (print TurboFan statistics of wasm compilations)
        type: bool  default: false
  --turbo-splitting (split nodes during scheduling in TurboFan)
        type: bool  default: true
  --function-context-specialization (enable function context specialization in TurboFan)
        type: bool  default: false
  --turbo-inlining (enable inlining in TurboFan)
        type: bool  default: true
  --max-inlined-bytecode-size (maximum size of bytecode for a single inlining)
        type: int  default: 500
  --max-inlined-bytecode-size-cumulative (maximum cumulative size of bytecode considered for inlining)
        type: int  default: 1000
  --max-inlined-bytecode-size-absolute (maximum cumulative size of bytecode considered for inlining)
        type: int  default: 5000
  --reserve-inline-budget-scale-factor (maximum cumulative size of bytecode considered for inlining)
        type: float  default: 1.2
  --max-inlined-bytecode-size-small (maximum size of bytecode considered for small function inlining)
        type: int  default: 30
  --max-optimized-bytecode-size (maximum bytecode size to be considered for optimization; too high values may cause the compiler to hit (release) assertions)
        type: int  default: 61440
  --min-inlining-frequency (minimum frequency for inlining)
        type: float  default: 0.15
  --polymorphic-inlining (polymorphic inlining)
        type: bool  default: true
  --stress-inline (set high thresholds for inlining to inline as much as possible)
        type: bool  default: false
  --trace-turbo-inlining (trace TurboFan inlining)
        type: bool  default: false
  --turbo-inline-array-builtins (inline array builtins in TurboFan code)
        type: bool  default: true
  --use-osr (use on-stack replacement)
        type: bool  default: true
  --trace-osr (trace on-stack replacement)
        type: bool  default: false
  --analyze-environment-liveness (analyze liveness of environment slots and zap dead values)
        type: bool  default: true
  --trace-environment-liveness (trace liveness of local variable slots)
        type: bool  default: false
  --turbo-load-elimination (enable load elimination in TurboFan)
        type: bool  default: true
  --trace-turbo-load-elimination (trace TurboFan load elimination)
        type: bool  default: false
  --turbo-profiling (enable basic block profiling in TurboFan)
        type: bool  default: false
  --turbo-profiling-verbose (enable basic block profiling in TurboFan, and include each function's schedule and disassembly in the output)
        type: bool  default: false
  --turbo-verify-allocation (verify register allocation in TurboFan)
        type: bool  default: false
  --turbo-move-optimization (optimize gap moves in TurboFan)
        type: bool  default: true
  --turbo-jt (enable jump threading in TurboFan)
        type: bool  default: true
  --turbo-loop-peeling (Turbofan loop peeling)
        type: bool  default: true
  --turbo-loop-variable (Turbofan loop variable optimization)
        type: bool  default: true
  --turbo-loop-rotation (Turbofan loop rotation)
        type: bool  default: true
  --turbo-cf-optimization (optimize control flow in TurboFan)
        type: bool  default: true
  --turbo-escape (enable escape analysis)
        type: bool  default: true
  --turbo-allocation-folding (Turbofan allocation folding)
        type: bool  default: true
  --turbo-instruction-scheduling (enable instruction scheduling in TurboFan)
        type: bool  default: false
  --turbo-stress-instruction-scheduling (randomly schedule instructions to stress dependency tracking)
        type: bool  default: false
  --turbo-store-elimination (enable store-store elimination in TurboFan)
        type: bool  default: true
  --trace-store-elimination (trace store elimination)
        type: bool  default: false
  --turbo-rewrite-far-jumps (rewrite far to near jumps (ia32,x64))
        type: bool  default: true
  --stress-gc-during-compilation (simulate GC/compiler thread race related to https://crbug.com/v8/8520)
        type: bool  default: false
  --turbo-fast-api-calls (enable fast API calls from TurboFan)
        type: bool  default: false
  --reuse-opt-code-count (don't discard optimized code for the specified number of deopts.)
        type: int  default: 0
  --turbo-nci (enable experimental native context independent code.)
        type: bool  default: false
  --turbo-nci-as-highest-tier (replace default TF with NCI code as the highest tier for testing purposes.)
        type: bool  default: false
  --print-nci-code (print native context independent code.)
        type: bool  default: false
  --trace-turbo-nci (trace native context independent code.)
        type: bool  default: false
  --turbo-collect-feedback-in-generic-lowering (enable experimental feedback collection in generic lowering.)
        type: bool  default: false
  --optimize-for-size (Enables optimizations which favor memory size over execution speed)
        type: bool  default: false
  --untrusted-code-mitigations (Enable mitigations for executing untrusted code)
        type: bool  default: false
  --expose-wasm (expose wasm interface to JavaScript)
        type: bool  default: true
  --assume-asmjs-origin (force wasm decoder to assume input is internal asm-wasm format)
        type: bool  default: false
  --wasm-num-compilation-tasks (maximum number of parallel compilation tasks for wasm)
        type: int  default: 128
  --wasm-write-protect-code-memory (write protect code memory on the wasm native heap)
        type: bool  default: false
  --wasm-async-compilation (enable actual asynchronous compilation for WebAssembly.compile)
        type: bool  default: true
  --wasm-test-streaming (use streaming compilation instead of async compilation for tests)
        type: bool  default: false
  --wasm-max-mem-pages (maximum initial number of 64KiB memory pages of a wasm instance)
        type: uint  default: 32767
  --wasm-max-mem-pages-growth (maximum number of 64KiB pages a Wasm memory can grow to)
        type: uint  default: 65536
  --wasm-max-table-size (maximum table size of a wasm instance)
        type: uint  default: 10000000
  --wasm-max-code-space (maximum committed code space for wasm (in MB))
        type: uint  default: 1024
  --wasm-tier-up (enable tier up to the optimizing compiler (requires --liftoff to have an effect))
        type: bool  default: true
  --trace-wasm-ast-start (start function for wasm AST trace (inclusive))
        type: int  default: 0
  --trace-wasm-ast-end (end function for wasm AST trace (exclusive))
        type: int  default: 0
  --liftoff (enable Liftoff, the baseline compiler for WebAssembly)
        type: bool  default: true
  --trace-wasm-memory (print all memory updates performed in wasm code)
        type: bool  default: false
  --wasm-tier-mask-for-testing (bitmask of functions to compile with TurboFan instead of Liftoff)
        type: int  default: 0
  --wasm-expose-debug-eval (Expose wasm evaluator support on the CDP)
        type: bool  default: false
  --validate-asm (validate asm.js modules before compiling)
        type: bool  default: true
  --suppress-asm-messages (don't emit asm.js related messages (for golden file testing))
        type: bool  default: false
  --trace-asm-time (log asm.js timing info to the console)
        type: bool  default: false
  --trace-asm-scanner (log tokens encountered by asm.js scanner)
        type: bool  default: false
  --trace-asm-parser (verbose logging of asm.js parse failures)
        type: bool  default: false
  --stress-validate-asm (try to validate everything as asm.js)
        type: bool  default: false
  --dump-wasm-module-path (directory to dump wasm modules to)
        type: string  default: nullptr
  --experimental-wasm-eh (enable prototype exception handling opcodes for wasm)
        type: bool  default: false
  --experimental-wasm-simd (enable prototype SIMD opcodes for wasm)
        type: bool  default: false
  --experimental-wasm-return-call (enable prototype return call opcodes for wasm)
        type: bool  default: false
  --experimental-wasm-compilation-hints (enable prototype compilation hints section for wasm)
        type: bool  default: false
  --experimental-wasm-gc (enable prototype garbage collection for wasm)
        type: bool  default: false
  --experimental-wasm-typed-funcref (enable prototype typed function references for wasm)
        type: bool  default: false
  --experimental-wasm-reftypes (enable prototype reference type opcodes for wasm)
        type: bool  default: false
  --experimental-wasm-threads (enable prototype thread opcodes for wasm)
        type: bool  default: false
  --experimental-wasm-type-reflection (enable prototype wasm type reflection in JS for wasm)
        type: bool  default: false
  --experimental-wasm-bigint (enable prototype JS BigInt support for wasm)
        type: bool  default: true
  --experimental-wasm-bulk-memory (enable prototype bulk memory opcodes for wasm)
        type: bool  default: true
  --experimental-wasm-mv (enable prototype multi-value support for wasm)
        type: bool  default: true
  --wasm-staging (enable staged wasm features)
        type: bool  default: false
  --wasm-opt (enable wasm optimization)
        type: bool  default: false
  --wasm-bounds-checks (enable bounds checks (disable for performance testing only))
        type: bool  default: true
  --wasm-stack-checks (enable stack checks (disable for performance testing only))
        type: bool  default: true
  --wasm-math-intrinsics (intrinsify some Math imports into wasm)
        type: bool  default: true
  --wasm-trap-handler (use signal handlers to catch out of bounds memory access in wasm (currently Linux x86_64 only))
        type: bool  default: true
  --wasm-fuzzer-gen-test (generate a test case when running a wasm fuzzer)
        type: bool  default: false
  --print-wasm-code (Print WebAssembly code)
        type: bool  default: false
  --print-wasm-stub-code (Print WebAssembly stub code)
        type: bool  default: false
  --asm-wasm-lazy-compilation (enable lazy compilation for asm-wasm modules)
        type: bool  default: false
  --wasm-lazy-compilation (enable lazy compilation for all wasm modules)
        type: bool  default: false
  --wasm-lazy-validation (enable lazy validation for lazily compiled wasm functions)
        type: bool  default: false
  --wasm-atomics-on-non-shared-memory (allow atomic operations on non-shared WebAssembly memory)
        type: bool  default: true
  --wasm-grow-shared-memory (allow growing shared WebAssembly memory objects)
        type: bool  default: true
  --wasm-simd-post-mvp (allow experimental SIMD operations for prototyping that are not included in the current proposal)
        type: bool  default: false
  --wasm-code-gc (enable garbage collection of wasm code)
        type: bool  default: true
  --trace-wasm-code-gc (trace garbage collection of wasm code)
        type: bool  default: false
  --stress-wasm-code-gc (stress test garbage collection of wasm code)
        type: bool  default: false
  --wasm-max-initial-code-space-reservation (maximum size of the initial wasm code space reservation (in MB))
        type: int  default: 0
  --frame-count (number of stack frames inspected by the profiler)
        type: int  default: 1
  --stress-sampling-allocation-profiler (Enables sampling allocation profiler with X as a sample interval)
        type: int  default: 0
  --lazy-new-space-shrinking (Enables the lazy new space shrinking strategy)
        type: bool  default: false
  --min-semi-space-size (min size of a semi-space (in MBytes), the new space consists of two semi-spaces)
        type: size_t  default: 0
  --max-semi-space-size (max size of a semi-space (in MBytes), the new space consists of two semi-spaces)
        type: size_t  default: 0
  --semi-space-growth-factor (factor by which to grow the new space)
        type: int  default: 2
  --max-old-space-size (max size of the old space (in Mbytes))
        type: size_t  default: 0
  --max-heap-size (max size of the heap (in Mbytes) both max_semi_space_size and max_old_space_size take precedence. All three flags cannot be specified at the same time.)
        type: size_t  default: 0
  --initial-heap-size (initial size of the heap (in Mbytes))
        type: size_t  default: 0
  --huge-max-old-generation-size (Increase max size of the old space to 4 GB for x64 systems withthe physical memory bigger than 16 GB)
        type: bool  default: true
  --initial-old-space-size (initial old space size (in Mbytes))
        type: size_t  default: 0
  --global-gc-scheduling (enable GC scheduling based on global memory)
        type: bool  default: true
  --gc-global (always perform global GCs)
        type: bool  default: false
  --random-gc-interval (Collect garbage after random(0, X) allocations. It overrides gc_interval.)
        type: int  default: 0
  --gc-interval (garbage collect after <n> allocations)
        type: int  default: -1
  --retain-maps-for-n-gc (keeps maps alive for <n> old space garbage collections)
        type: int  default: 2
  --trace-gc (print one trace line following each garbage collection)
        type: bool  default: false
  --trace-gc-nvp (print one detailed trace line in name=value format after each garbage collection)
        type: bool  default: false
  --trace-gc-ignore-scavenger (do not print trace line after scavenger collection)
        type: bool  default: false
  --trace-idle-notification (print one trace line following each idle notification)
        type: bool  default: false
  --trace-idle-notification-verbose (prints the heap state used by the idle notification)
        type: bool  default: false
  --trace-gc-verbose (print more details following each garbage collection)
        type: bool  default: false
  --trace-gc-freelists (prints details of each freelist before and after each major garbage collection)
        type: bool  default: false
  --trace-gc-freelists-verbose (prints details of freelists of each page before and after each major garbage collection)
        type: bool  default: false
  --trace-evacuation-candidates (Show statistics about the pages evacuation by the compaction)
        type: bool  default: false
  --trace-allocations-origins (Show statistics about the origins of allocations. Combine with --no-inline-new to track allocations from generated code)
        type: bool  default: false
  --trace-allocation-stack-interval (print stack trace after <n> free-list allocations)
        type: int  default: -1
  --trace-duplicate-threshold-kb (print duplicate objects in the heap if their size is more than given threshold)
        type: int  default: 0
  --trace-fragmentation (report fragmentation for old space)
        type: bool  default: false
  --trace-fragmentation-verbose (report fragmentation for old space (detailed))
        type: bool  default: false
  --minor-mc-trace-fragmentation (trace fragmentation after marking)
        type: bool  default: false
  --trace-evacuation (report evacuation statistics)
        type: bool  default: false
  --trace-mutator-utilization (print mutator utilization, allocation speed, gc speed)
        type: bool  default: false
  --incremental-marking (use incremental marking)
        type: bool  default: true
  --incremental-marking-wrappers (use incremental marking for marking wrappers)
        type: bool  default: true
  --incremental-marking-task (use tasks for incremental marking)
        type: bool  default: true
  --incremental-marking-soft-trigger (threshold for starting incremental marking via a task in percent of available space: limit - size)
        type: int  default: 0
  --incremental-marking-hard-trigger (threshold for starting incremental marking immediately in percent of available space: limit - size)
        type: int  default: 0
  --trace-unmapper (Trace the unmapping)
        type: bool  default: false
  --parallel-scavenge (parallel scavenge)
        type: bool  default: true
  --scavenge-task (schedule scavenge tasks)
        type: bool  default: true
  --scavenge-task-trigger (scavenge task trigger in percent of the current heap limit)
        type: int  default: 80
  --scavenge-separate-stack-scanning (use a separate phase for stack scanning in scavenge)
        type: bool  default: false
  --trace-parallel-scavenge (trace parallel scavenge)
        type: bool  default: false
  --write-protect-code-memory (write protect code memory)
        type: bool  default: true
  --concurrent-marking (use concurrent marking)
        type: bool  default: true
  --concurrent-array-buffer-sweeping (concurrently sweep array buffers)
        type: bool  default: true
  --concurrent-allocation (concurrently allocate in old space)
        type: bool  default: false
  --local-heaps (allow heap access from background tasks)
        type: bool  default: false
  --stress-concurrent-allocation (start background threads that allocate memory)
        type: bool  default: false
  --parallel-marking (use parallel marking in atomic pause)
        type: bool  default: true
  --ephemeron-fixpoint-iterations (number of fixpoint iterations it takes to switch to linear ephemeron algorithm)
        type: int  default: 10
  --trace-concurrent-marking (trace concurrent marking)
        type: bool  default: false
  --concurrent-store-buffer (use concurrent store buffer processing)
        type: bool  default: true
  --concurrent-sweeping (use concurrent sweeping)
        type: bool  default: true
  --parallel-compaction (use parallel compaction)
        type: bool  default: true
  --parallel-pointer-update (use parallel pointer update during compaction)
        type: bool  default: true
  --detect-ineffective-gcs-near-heap-limit (trigger out-of-memory failure to avoid GC storm near heap limit)
        type: bool  default: true
  --trace-incremental-marking (trace progress of the incremental marking)
        type: bool  default: false
  --trace-stress-marking (trace stress marking progress)
        type: bool  default: false
  --trace-stress-scavenge (trace stress scavenge progress)
        type: bool  default: false
  --track-gc-object-stats (track object counts and memory usage)
        type: bool  default: false
  --trace-gc-object-stats (trace object counts and memory usage)
        type: bool  default: false
  --trace-zone-stats (trace zone memory usage)
        type: bool  default: false
  --zone-stats-tolerance (report a tick only when allocated zone memory changes by this amount)
        type: size_t  default: 1048576
  --track-retaining-path (enable support for tracking retaining path)
        type: bool  default: false
  --concurrent-array-buffer-freeing (free array buffer allocations on a background thread)
        type: bool  default: true
  --gc-stats (Used by tracing internally to enable gc statistics)
        type: int  default: 0
  --track-detached-contexts (track native contexts that are expected to be garbage collected)
        type: bool  default: true
  --trace-detached-contexts (trace native contexts that are expected to be garbage collected)
        type: bool  default: false
  --move-object-start (enable moving of object starts)
        type: bool  default: true
  --memory-reducer (use memory reducer)
        type: bool  default: true
  --memory-reducer-for-small-heaps (use memory reducer for small heaps)
        type: bool  default: true
  --heap-growing-percent (specifies heap growing factor as (1 + heap_growing_percent/100))
        type: int  default: 0
  --v8-os-page-size (override OS page size (in KBytes))
        type: int  default: 0
  --always-compact (Perform compaction on every full GC)
        type: bool  default: false
  --never-compact (Never perform compaction on full GC - testing only)
        type: bool  default: false
  --compact-code-space (Compact code space on full collections)
        type: bool  default: true
  --flush-bytecode (flush of bytecode when it has not been executed recently)
        type: bool  default: true
  --stress-flush-bytecode (stress bytecode flushing)
        type: bool  default: false
  --use-marking-progress-bar (Use a progress bar to scan large objects in increments when incremental marking is active.)
        type: bool  default: true
  --stress-per-context-marking-worklist (Use per-context worklist for marking)
        type: bool  default: false
  --force-marking-deque-overflows (force overflows of marking deque by reducing it's size to 64 words)
        type: bool  default: false
  --stress-compaction (stress the GC compactor to flush out bugs (implies --force_marking_deque_overflows))
        type: bool  default: false
  --stress-compaction-random (Stress GC compaction by selecting random percent of pages as evacuation candidates. It overrides stress_compaction.)
        type: bool  default: false
  --stress-incremental-marking (force incremental marking for small heaps and run it more often)
        type: bool  default: false
  --fuzzer-gc-analysis (prints number of allocations and enables analysis mode for gc fuzz testing, e.g. --stress-marking, --stress-scavenge)
        type: bool  default: false
  --stress-marking (force marking at random points between 0 and X (inclusive) percent of the regular marking start limit)
        type: int  default: 0
  --stress-scavenge (force scavenge at random points between 0 and X (inclusive) percent of the new space capacity)
        type: int  default: 0
  --gc-experiment-background-schedule (new background GC schedule heuristics)
        type: bool  default: false
  --gc-experiment-less-compaction (less compaction in non-memory reducing mode)
        type: bool  default: false
  --disable-abortjs (disables AbortJS runtime function)
        type: bool  default: false
  --randomize-all-allocations (randomize virtual memory reservations by ignoring any hints passed when allocating pages)
        type: bool  default: false
  --manual-evacuation-candidates-selection (Test mode only flag. It allows an unit test to select evacuation candidates pages (requires --stress_compaction).)
        type: bool  default: false
  --fast-promotion-new-space (fast promote new space on high survival rates)
        type: bool  default: false
  --clear-free-memory (initialize free memory with 0)
        type: bool  default: false
  --young-generation-large-objects (allocates large objects by default in the young generation large object space)
        type: bool  default: true
  --debug-code (generate extra code (assertions) for debugging)
        type: bool  default: false
  --code-comments (emit comments in code disassembly; for more readable source positions you should add --no-concurrent_recompilation)
        type: bool  default: false
  --enable-sse3 (enable use of SSE3 instructions if available)
        type: bool  default: true
  --enable-ssse3 (enable use of SSSE3 instructions if available)
        type: bool  default: true
  --enable-sse4-1 (enable use of SSE4.1 instructions if available)
        type: bool  default: true
  --enable-sse4-2 (enable use of SSE4.2 instructions if available)
        type: bool  default: true
  --enable-sahf (enable use of SAHF instruction if available (X64 only))
        type: bool  default: true
  --enable-avx (enable use of AVX instructions if available)
        type: bool  default: true
  --enable-fma3 (enable use of FMA3 instructions if available)
        type: bool  default: true
  --enable-bmi1 (enable use of BMI1 instructions if available)
        type: bool  default: true
  --enable-bmi2 (enable use of BMI2 instructions if available)
        type: bool  default: true
  --enable-lzcnt (enable use of LZCNT instruction if available)
        type: bool  default: true
  --enable-popcnt (enable use of POPCNT instruction if available)
        type: bool  default: true
  --arm-arch (generate instructions for the selected ARM architecture if available: armv6, armv7, armv7+sudiv or armv8)
        type: string  default: armv8
  --force-long-branches (force all emitted branches to be in long mode (MIPS/PPC only))
        type: bool  default: false
  --mcpu (enable optimization for specific cpu)
        type: string  default: auto
  --partial-constant-pool (enable use of partial constant pools (X64 only))
        type: bool  default: true
  --sim-arm64-optional-features (enable optional features on the simulator for testing: none or all)
        type: string  default: none
  --enable-source-at-csa-bind (Include source information in the binary at CSA bind locations.)
        type: bool  default: false
  --enable-armv7 (deprecated (use --arm_arch instead))
        type: maybe_bool  default: unset
  --enable-vfp3 (deprecated (use --arm_arch instead))
        type: maybe_bool  default: unset
  --enable-32dregs (deprecated (use --arm_arch instead))
        type: maybe_bool  default: unset
  --enable-neon (deprecated (use --arm_arch instead))
        type: maybe_bool  default: unset
  --enable-sudiv (deprecated (use --arm_arch instead))
        type: maybe_bool  default: unset
  --enable-armv8 (deprecated (use --arm_arch instead))
        type: maybe_bool  default: unset
  --enable-regexp-unaligned-accesses (enable unaligned accesses for the regexp engine)
        type: bool  default: true
  --script-streaming (enable parsing on background)
        type: bool  default: true
  --stress-background-compile (stress test parsing on background)
        type: bool  default: false
  --finalize-streaming-on-background (perform the script streaming finalization on the background thread)
        type: bool  default: false
  --disable-old-api-accessors (Disable old-style API accessors whose setters trigger through the prototype chain)
        type: bool  default: false
  --expose-gc (expose gc extension)
        type: bool  default: false
  --expose-gc-as (expose gc extension under the specified name)
        type: string  default: nullptr
  --expose-externalize-string (expose externalize string extension)
        type: bool  default: false
  --expose-trigger-failure (expose trigger-failure extension)
        type: bool  default: false
  --stack-trace-limit (number of stack frames to capture)
        type: int  default: 10
  --builtins-in-stack-traces (show built-in functions in stack traces)
        type: bool  default: false
  --experimental-stack-trace-frames (enable experimental frames (API/Builtins) and stack trace layout)
        type: bool  default: false
  --disallow-code-generation-from-strings (disallow eval and friends)
        type: bool  default: false
  --expose-async-hooks (expose async_hooks object)
        type: bool  default: false
  --expose-cputracemark-as (expose cputracemark extension under the specified name)
        type: string  default: nullptr
  --allow-unsafe-function-constructor (allow invoking the function constructor without security checks)
        type: bool  default: false
  --force-slow-path (always take the slow path for builtins)
        type: bool  default: false
  --test-small-max-function-context-stub-size (enable testing the function context size overflow path by making the maximum size smaller)
        type: bool  default: false
  --inline-new (use fast inline allocation)
        type: bool  default: true
  --trace (trace javascript function calls)
        type: bool  default: false
  --trace-wasm (trace wasm function calls)
        type: bool  default: false
  --lazy (use lazy compilation)
        type: bool  default: true
  --max-lazy (ignore eager compilation hints)
        type: bool  default: false
  --trace-opt (trace lazy optimization)
        type: bool  default: false
  --trace-opt-verbose (extra verbose compilation tracing)
        type: bool  default: false
  --trace-opt-stats (trace lazy optimization statistics)
        type: bool  default: false
  --trace-deopt (trace optimize function deoptimization)
        type: bool  default: false
  --trace-file-names (include file names in trace-opt/trace-deopt output)
        type: bool  default: false
  --always-opt (always try to optimize functions)
        type: bool  default: false
  --always-osr (always try to OSR functions)
        type: bool  default: false
  --prepare-always-opt (prepare for turning on always opt)
        type: bool  default: false
  --trace-serializer (print code serializer trace)
        type: bool  default: false
  --compilation-cache (enable compilation cache)
        type: bool  default: true
  --cache-prototype-transitions (cache prototype transitions)
        type: bool  default: true
  --parallel-compile-tasks (enable parallel compile tasks)
        type: bool  default: false
  --compiler-dispatcher (enable compiler dispatcher)
        type: bool  default: false
  --trace-compiler-dispatcher (trace compiler dispatcher activity)
        type: bool  default: false
  --cpu-profiler-sampling-interval (CPU profiler sampling interval in microseconds)
        type: int  default: 1000
  --trace-side-effect-free-debug-evaluate (print debug messages for side-effect-free debug-evaluate for testing)
        type: bool  default: false
  --hard-abort (abort by crashing)
        type: bool  default: true
  --expose-inspector-scripts (expose injected-script-source.js for debugging)
        type: bool  default: false
  --stack-size (default size of stack region v8 is allowed to use (in kBytes))
        type: int  default: 984
  --max-stack-trace-source-length (maximum length of function source code printed in a stack trace.)
        type: int  default: 300
  --clear-exceptions-on-js-entry (clear pending exceptions when entering JavaScript)
        type: bool  default: false
  --histogram-interval (time interval in ms for aggregating memory histograms)
        type: int  default: 600000
  --heap-profiler-trace-objects (Dump heap object allocations/movements/size_updates)
        type: bool  default: false
  --heap-profiler-use-embedder-graph (Use the new EmbedderGraph API to get embedder nodes)
        type: bool  default: true
  --heap-snapshot-string-limit (truncate strings to this length in the heap snapshot)
        type: int  default: 1024
  --sampling-heap-profiler-suppress-randomness (Use constant sample intervals to eliminate test flakiness)
        type: bool  default: false
  --use-idle-notification (Use idle notification to reduce memory footprint.)
        type: bool  default: true
  --trace-ic (trace inline cache state transitions for tools/ic-processor)
        type: bool  default: false
  --modify-field-representation-inplace (enable in-place field representation updates)
        type: bool  default: true
  --max-polymorphic-map-count (maximum number of maps to track in POLYMORPHIC state)
        type: int  default: 4
  --native-code-counters (generate extra code for manipulating stats counters)
        type: bool  default: false
  --thin-strings (Enable ThinString support)
        type: bool  default: true
  --trace-prototype-users (Trace updates to prototype user tracking)
        type: bool  default: false
  --trace-for-in-enumerate (Trace for-in enumerate slow-paths)
        type: bool  default: false
  --trace-maps (trace map creation)
        type: bool  default: false
  --trace-maps-details (also log map details)
        type: bool  default: true
  --allow-natives-syntax (allow natives syntax)
        type: bool  default: false
  --allow-natives-for-differential-fuzzing (allow only natives explicitly allowlisted for differential fuzzers)
        type: bool  default: false
  --parse-only (only parse the sources)
        type: bool  default: false
  --trace-sim (Trace simulator execution)
        type: bool  default: false
  --debug-sim (Enable debugging the simulator)
        type: bool  default: false
  --check-icache (Check icache flushes in ARM and MIPS simulator)
        type: bool  default: false
  --stop-sim-at (Simulator stop after x number of instructions)
        type: int  default: 0
  --sim-stack-alignment (Stack alingment in bytes in simulator (4 or 8, 8 is default))
        type: int  default: 8
  --sim-stack-size (Stack size of the ARM64, MIPS64 and PPC64 simulator in kBytes (default is 2 MB))
        type: int  default: 2048
  --log-colour (When logging, try to use coloured output.)
        type: bool  default: true
  --trace-sim-messages (Trace simulator debug messages. Implied by --trace-sim.)
        type: bool  default: false
  --async-stack-traces (include async stack traces in Error.stack)
        type: bool  default: true
  --stack-trace-on-illegal (print stack trace when an illegal exception is thrown)
        type: bool  default: false
  --abort-on-uncaught-exception (abort program (dump core) when an uncaught exception is thrown)
        type: bool  default: false
  --correctness-fuzzer-suppressions (Suppress certain unspecified behaviors to ease correctness fuzzing: Abort program when the stack overflows or a string exceeds maximum length (as opposed to throwing RangeError). Use a fixed suppression string for error messages.)
        type: bool  default: false
  --randomize-hashes (randomize hashes to avoid predictable hash collisions (with snapshots this option cannot override the baked-in seed))
        type: bool  default: true
  --rehash-snapshot (rehash strings from the snapshot to override the baked-in seed)
        type: bool  default: true
  --hash-seed (Fixed seed to use to hash property keys (0 means random)(with snapshots this option cannot override the baked-in seed))
        type: uint64  default: 0
  --random-seed (Default seed for initializing random generator (0, the default, means to use system random).)
        type: int  default: 0
  --fuzzer-random-seed (Default seed for initializing fuzzer random generator (0, the default, means to use v8's random number generator seed).)
        type: int  default: 0
  --trace-rail (trace RAIL mode)
        type: bool  default: false
  --print-all-exceptions (print exception object and stack trace on each thrown exception)
        type: bool  default: false
  --detailed-error-stack-trace (includes arguments for each function call in the error stack frames array)
        type: bool  default: false
  --adjust-os-scheduling-parameters (adjust OS specific scheduling params for the isolate)
        type: bool  default: true
  --runtime-call-stats (report runtime call counts and times)
        type: bool  default: false
  --rcs (report runtime call counts and times)
        type: bool  default: false
  --rcs-cpu-time (report runtime times in cpu time (the default is wall time))
        type: bool  default: false
  --profile-deserialization (Print the time it takes to deserialize the snapshot.)
        type: bool  default: false
  --serialization-statistics (Collect statistics on serialized objects.)
        type: bool  default: false
  --serialization-chunk-size (Custom size for serialization chunks)
        type: uint  default: 4096
  --regexp-optimization (generate optimized regexp code)
        type: bool  default: true
  --regexp-mode-modifiers (enable inline flags in regexp.)
        type: bool  default: false
  --regexp-interpret-all (interpret all regexp code)
        type: bool  default: false
  --regexp-tier-up (enable regexp interpreter and tier up to the compiler after the number of executions set by the tier up ticks flag)
        type: bool  default: true
  --regexp-tier-up-ticks (set the number of executions for the regexp interpreter before tiering-up to the compiler)
        type: int  default: 1
  --regexp-peephole-optimization (enable peephole optimization for regexp bytecode)
        type: bool  default: true
  --trace-regexp-peephole-optimization (trace regexp bytecode peephole optimization)
        type: bool  default: false
  --trace-regexp-bytecodes (trace regexp bytecode execution)
        type: bool  default: false
  --trace-regexp-assembler (trace regexp macro assembler calls.)
        type: bool  default: false
  --trace-regexp-parser (trace regexp parsing)
        type: bool  default: false
  --trace-regexp-tier-up (trace regexp tiering up execution)
        type: bool  default: false
  --testing-bool-flag (testing_bool_flag)
        type: bool  default: true
  --testing-maybe-bool-flag (testing_maybe_bool_flag)
        type: maybe_bool  default: unset
  --testing-int-flag (testing_int_flag)
        type: int  default: 13
  --testing-float-flag (float-flag)
        type: float  default: 2.5
  --testing-string-flag (string-flag)
        type: string  default: Hello, world!
  --testing-prng-seed (Seed used for threading test randomness)
        type: int  default: 42
  --testing-d8-test-runner (test runner turns on this flag to enable a check that the function was prepared for optimization before marking it for optimization)
        type: bool  default: false
  --fuzzing (Fuzzers use this flag to signal that they are ... fuzzing. This causes intrinsics to fail silently (e.g. return undefined) on invalid usage.)
        type: bool  default: false
  --embedded-src (Path for the generated embedded data file. (mksnapshot only))
        type: string  default: nullptr
  --embedded-variant (Label to disambiguate symbols in embedded data file. (mksnapshot only))
        type: string  default: nullptr
  --startup-src (Write V8 startup as C++ src. (mksnapshot only))
        type: string  default: nullptr
  --startup-blob (Write V8 startup blob file. (mksnapshot only))
        type: string  default: nullptr
  --target-arch (The mksnapshot target arch. (mksnapshot only))
        type: string  default: nullptr
  --target-os (The mksnapshot target os. (mksnapshot only))
        type: string  default: nullptr
  --target-is-simulator (Instruct mksnapshot that the target is meant to run in the simulator and it can generate simulator-specific instructions. (mksnapshot only))
        type: bool  default: false
  --minor-mc-parallel-marking (use parallel marking for the young generation)
        type: bool  default: true
  --trace-minor-mc-parallel-marking (trace parallel marking for the young generation)
        type: bool  default: false
  --minor-mc (perform young generation mark compact GCs)
        type: bool  default: false
  --help (Print usage message, including flags, on console)
        type: bool  default: true
  --dump-counters (Dump counters on exit)
        type: bool  default: false
  --dump-counters-nvp (Dump counters as name-value pairs on exit)
        type: bool  default: false
  --use-external-strings (Use external strings for source code)
        type: bool  default: false
  --map-counters (Map counters to a file)
        type: string  default:
  --mock-arraybuffer-allocator (Use a mock ArrayBuffer allocator for testing.)
        type: bool  default: false
  --mock-arraybuffer-allocator-limit (Memory limit for mock ArrayBuffer allocator used to simulate OOM for testing.)
        type: size_t  default: 0
  --gdbjit (enable GDBJIT interface)
        type: bool  default: false
  --gdbjit-full (enable GDBJIT interface for all code objects)
        type: bool  default: false
  --gdbjit-dump (dump elf objects with debug info to disk)
        type: bool  default: false
  --gdbjit-dump-filter (dump only objects containing this substring)
        type: string  default:
  --log (Minimal logging (no API, code, GC, suspect, or handles samples).)
        type: bool  default: false
  --log-all (Log all events to the log file.)
        type: bool  default: false
  --log-api (Log API events to the log file.)
        type: bool  default: false
  --log-code (Log code events to the log file without profiling.)
        type: bool  default: false
  --log-handles (Log global handle events.)
        type: bool  default: false
  --log-suspect (Log suspect operations.)
        type: bool  default: false
  --log-source-code (Log source code.)
        type: bool  default: false
  --log-function-events (Log function events (parse, compile, execute) separately.)
        type: bool  default: false
  --prof (Log statistical profiling information (implies --log-code).)
        type: bool  default: false
  --detailed-line-info (Always generate detailed line information for CPU profiling.)
        type: bool  default: false
  --prof-sampling-interval (Interval for --prof samples (in microseconds).)
        type: int  default: 1000
  --prof-cpp (Like --prof, but ignore generated code.)
        type: bool  default: false
  --prof-browser-mode (Used with --prof, turns on browser-compatible mode for profiling.)
        type: bool  default: true
  --logfile (Specify the name of the log file.)
        type: string  default: v8.log
  --logfile-per-isolate (Separate log files for each isolate.)
        type: bool  default: true
  --ll-prof (Enable low-level linux profiler.)
        type: bool  default: false
  --gc-fake-mmap (Specify the name of the file for fake gc mmap used in ll_prof)
        type: string  default: /tmp/__v8_gc__
  --log-internal-timer-events (Time internal events.)
        type: bool  default: false
  --redirect-code-traces (output deopt information and disassembly into file code-<pid>-<isolate id>.asm)
        type: bool  default: false
  --redirect-code-traces-to (output deopt information and disassembly into the given file)
        type: string  default: nullptr
  --print-opt-source (print source code of optimized and inlined functions)
        type: bool  default: false
  --vtune-prof-annotate-wasm (Used when v8_enable_vtunejit is enabled, load wasm source map and provide annotate support (experimental).)
        type: bool  default: false
  --win64-unwinding-info (Enable unwinding info for Windows/x64)
        type: bool  default: true
  --interpreted-frames-native-stack (Show interpreted frames on the native stack (useful for external profilers).)
        type: bool  default: false
  --predictable (enable predictable mode)
        type: bool  default: false
  --predictable-gc-schedule (Predictable garbage collection schedule. Fixes heap growing, idle, and memory reducing behavior.)
        type: bool  default: false
  --single-threaded (disable the use of background tasks)
        type: bool  default: false
  --single-threaded-gc (disable the use of background gc tasks)
        type: bool  default: false

Particularly useful ones:

--async-stack-trace

Continuous Benchmarks

See our benchmarks over here

The benchmark chart supposes https://github.com/denoland/benchmark_data/blob/gh-pages/data.json has the type BenchmarkData[] where BenchmarkData is defined like the below:

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;
  };
}

Deno Style Guide

Table of Contents

Copyright Headers

Most modules in the repository should have the following copyright header:

// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

If the code originates elsewhere, ensure that the file has the proper copyright headers. We only allow MIT, BSD, and Apache licensed code.

Use underscores, not dashes in filenames.

Example: Use file_server.ts instead of file-server.ts.

Add tests for new features.

Each module should contain or be accompanied by tests for its public functionality.

TODO Comments

TODO comments should usually include an issue or the author's github username in parentheses. Example:

// TODO(ry): Add tests.
// TODO(#123): Support Windows.
// FIXME(#349): Sometimes panics.

Meta-programming is discouraged. Including the use of Proxy.

Be explicit even when it means more code.

There are some situations where it may make sense to use such techniques, but in the vast majority of cases it does not.

Inclusive code

Please follow the guidelines for inclusive code outlined at https://chromium.googlesource.com/chromium/src/+/master/styleguide/inclusive_code.md.

Rust

Follow Rust conventions and be consistent with existing code.

Typescript

The TypeScript portions of the codebase include cli/js for the built-ins and the standard library std.

Use TypeScript instead of JavaScript.

Use the term "module" instead of "library" or "package".

For clarity and consistency avoid the terms "library" and "package". Instead use "module" to refer to a single JS or TS file and also to refer to a directory of TS/JS code.

Do not use the filename index.ts/index.js.

Deno does not treat "index.js" or "index.ts" in a special way. By using these filenames, it suggests that they can be left out of the module specifier when they cannot. This is confusing.

If a directory of code needs a default entry point, use the filename mod.ts. The filename mod.ts follows Rust’s convention, is shorter than index.ts, and doesn’t come with any preconceived notions about how it might work.

Exported functions: max 2 args, put the rest into an options object.

When designing function interfaces, stick to the following rules.

  1. A function that is part of the public API takes 0-2 required arguments, plus (if necessary) an options object (so max 3 total).

  2. Optional parameters should generally go into the options object.

    An optional parameter that's not in an options object might be acceptable if there is only one, and it seems inconceivable that we would add more optional parameters in the future.

  3. The 'options' argument is the only argument that is a regular 'Object'.

    Other arguments can be objects, but they must be distinguishable from a 'plain' Object runtime, by having either:

    • a distinguishing prototype (e.g. Array, Map, Date, class MyThing)
    • a well-known symbol property (e.g. an iterable with Symbol.iterator).

    This allows the API to evolve in a backwards compatible way, even when the position of the options object changes.

// BAD: optional parameters not part of options object. (#2)
export function resolve(
  hostname: string,
  family?: "ipv4" | "ipv6",
  timeout?: number,
): IPAddress[] {}

// GOOD.
export interface ResolveOptions {
  family?: "ipv4" | "ipv6";
  timeout?: number;
}
export function resolve(
  hostname: string,
  options: ResolveOptions = {},
): IPAddress[] {}
export interface Environment {
  [key: string]: string;
}

// BAD: `env` could be a regular Object and is therefore indistinguishable
// from an options object. (#3)
export function runShellWithEnv(cmdline: string, env: Environment): string {}

// GOOD.
export interface RunShellOptions {
  env: Environment;
}
export function runShellWithEnv(
  cmdline: string,
  options: RunShellOptions,
): string {}
// BAD: more than 3 arguments (#1), multiple optional parameters (#2).
export function renameSync(
  oldname: string,
  newname: string,
  replaceExisting?: boolean,
  followLinks?: boolean,
) {}

// GOOD.
interface RenameOptions {
  replaceExisting?: boolean;
  followLinks?: boolean;
}
export function renameSync(
  oldname: string,
  newname: string,
  options: RenameOptions = {},
) {}
// BAD: too many arguments. (#1)
export function pwrite(
  fd: number,
  buffer: TypedArray,
  offset: number,
  length: number,
  position: number,
) {}

// BETTER.
export interface PWrite {
  fd: number;
  buffer: TypedArray;
  offset: number;
  length: number;
  position: number;
}
export function pwrite(options: PWrite) {}

Minimize dependencies; do not make circular imports.

Although cli/js and std have no external dependencies, we must still be careful to keep internal dependencies simple and manageable. In particular, be careful not to introduce circular imports.

If a filename starts with an underscore: _foo.ts, do not link to it.

Sometimes there may be situations where an internal module is necessary but its API is not meant to be stable or linked to. In this case prefix it with an underscore. By convention, only files in its own directory should import it.

Use JSDoc for exported symbols.

We strive for complete documentation. Every exported symbol ideally should have a documentation line.

If possible, use a single line for the JS Doc. Example:

/** foo does bar. */
export function foo() {
  // ...
}

It is important that documentation is easily human readable, but there is also a need to provide additional styling information to ensure generated documentation is more rich text. Therefore JSDoc should generally follow markdown markup to enrich the text.

While markdown supports HTML tags, it is forbidden in JSDoc blocks.

Code string literals should be braced with the back-tick (`) instead of quotes. For example:

/** Import something from the `deno` module. */

Do not document function arguments unless they are non-obvious of their intent (though if they are non-obvious intent, the API should be considered anyways). Therefore @param should generally not be used. If @param is used, it should not include the type as TypeScript is already strongly typed.

/**
 * Function with non obvious param.
 * @param foo Description of non obvious parameter.
 */

Vertical spacing should be minimized whenever possible. Therefore single line comments should be written as:

/** This is a good single line JSDoc. */

And not

/**
 * This is a bad single line JSDoc.
 */

Code examples should not utilise the triple-back tick (```) notation or tags. They should just be marked by indentation, which requires a break before the block and 6 additional spaces for each line of the example. This is 4 more than the first column of the comment. For example:

/** A straight forward comment and an example:
 *
 *       import { foo } from "deno";
 *       foo("bar");
 */

Code examples should not contain additional comments. It is already inside a comment. If it needs further comments it is not a good example.

Each module should come with a test module.

Every module with public functionality foo.ts should come with a test module foo_test.ts. A test for a cli/js module should go in cli/js/tests due to their different contexts, otherwise it should just be a sibling to the tested module.

Unit Tests should be explicit.

For a better understanding of the tests, function should be correctly named as its prompted throughout the test command. Like:

test myTestFunction ... ok

Example of test:

import { assertEquals } from "https://deno.land/std@v0.11/testing/asserts.ts";
import { foo } from "./mod.ts";

Deno.test("myTestFunction" function() {
  assertEquals(foo(), { bar: "bar" });
});

Top level functions should not use arrow syntax.

Top level functions should use the function keyword. Arrow syntax should be limited to closures.

Bad

export const foo = (): string => {
  return "bar";
};

Good

export function foo(): string {
  return "bar";
}

std

Do not depend on external code.

https://deno.land/std/ is intended to be baseline functionality that all Deno programs can rely on. We want to guarantee to users that this code does not include potentially unreviewed third party code.

Document and maintain browser compatiblity.

If a module is browser compatible, include the following in the JSDoc at the top of the module:

/** This module is browser compatible. */

Maintain browser compatibility for such a module by either not using the global Deno namespace or feature-testing for it. Make sure any new dependencies are also browser compatible.

Internal details

Deno and Linux analogy

LinuxDeno
ProcessesWeb Workers
SyscallsOps
File descriptors (fd)Resource ids (rid)
SchedulerTokio
Userland: libc++ / glib / boosthttps://deno.land/std/
/proc/$$/statDeno.metrics()
man pagesdeno types

Resources

Resources (AKA rid) are Deno's version of file descriptors. They are integer values used to refer to open files, sockets, and other concepts. For testing it would be good to be able to query the system for how many open resources there are.

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

Metrics

Metrics is Deno's internal counter for various statistics.

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

Schematic diagram

architectural schematic

この章では、ランタイムの詳細を学習するために使用できるいくつかのサンプルプログラムを見つけることができます。

ベーシック

アドバンス

Hello World

Denoは、JavaScriptとTypeScriptの両方の安全なランタイムです。以下のhello worldの例は、同じ機能をJavaScriptまたはTypeScriptで作成できることを示しているので、Denoは両方を実行します。

JavaScript

このJavaScriptの例では、メッセージHello [name]がコンソールに出力され、コードにより、提供された名前が大文字で使用されることが保証されます。

Command: deno run hello-world.js

function capitalize(word) {
  return word.charAt(0).toUpperCase() + word.slice(1);
}

function hello(name) {
  return "Hello " + capitalize(name);
}

console.log(hello("john"));
console.log(hello("Sarah"));
console.log(hello("kai"));

/**
 * Output:
 *
 * Hello John
 * Hello Sarah
 * Hello Kai
**/

TypeScript

このTypeScriptの例は、上記のJavaScriptの例とまったく同じです。コードには、TypeScriptがサポートする追加の型情報が含まれています。

deno runコマンドを使うのはまったく同じです。*.jsファイルではなく*.tsファイルを参照するだけです。

Command: deno run hello-world.ts

function capitalize(word: string): string {
  return word.charAt(0).toUpperCase() + word.slice(1);
}

function hello(name: string): string {
  return "Hello " + capitalize(name);
}

console.log(hello("john"));
console.log(hello("Sarah"));
console.log(hello("kai"));

/**
 * Output:
 *
 * Hello John
 * Hello Sarah
 * Hello Kai
**/

モジュールのインポートとエクスポート

Denoはデフォルトで、JavaScriptとTypeScriptの両方でモジュールをインポートする方法を標準化しています。 ECMAScript 6のimport/export標準に従いますが、注意点が1つあります。ファイルタイプはインポートステートメントの最後に含める必要があります。

import {
  add,
  multiply,
} from "./arithmetic.ts";

依存関係も直接インポートされ、パッケージ管理のオーバーヘッドはありません。ローカルモジュールは、リモートモジュールとまったく同じ方法でインポートされます。以下の例に示すように、同じ機能をローカルモジュールまたはリモートモジュールを使用して同じ方法で作成できます。

ローカルインポート

この例では、add関数とmultiply関数がローカルのarithmetic.tsモジュールからインポートされています。

Command: deno run local.ts

import { add, multiply } from "./arithmetic.ts";

function totalCost(outbound: number, inbound: number, tax: number): number {
  return multiply(add(outbound, inbound), tax);
}

console.log(totalCost(19, 31, 1.2));
console.log(totalCost(45, 27, 1.15));

/**
 * Output
 *
 * 60
 * 82.8
 */

エクスポート

上記の例では、add関数とmultiply関数はローカルに保存された算術モジュールからインポートされます。これを可能にするには、算術モジュールに保存されている関数をエクスポートする必要があります。

これを行うには、以下に示すように、関数シグネチャの先頭にexportのキーワードを追加します。

export function add(a: number, b: number): number {
  return a + b;
}

export function multiply(a: number, b: number): number {
  return a * b;
}

外部モジュール内でアクセスできる必要があるすべての関数、クラス、定数、変数はエクスポートする必要があります。それらにexportキーワードを前に付けるか、ファイルの下部にあるexportステートメントに含めます。

ECMAScriptエクスポート機能の詳細については、MDNドキュメントをご覧ください。

リモートインポート

上記のローカルインポートの例では、addおよびmultiplyメソッドがローカルに保存された算術モジュールからインポートされます。同じ機能は、リモートモジュールからaddメソッドとmultiplyメソッドをインポートすることによっても作成できます。

この場合、バージョン番号を含むRamdaモジュールが参照されます。また、JavaScriptモジュールがTypeSriptモジュールに直接インポートされることにも注意してください。Denoはこれを問題なく処理します。

Command: deno run ./remote.ts

import {
  add,
  multiply,
} from "https://x.nest.land/ramda@0.27.0/source/index.js";

function totalCost(outbound: number, inbound: number, tax: number): number {
  return multiply(add(outbound, inbound), tax);
}

console.log(totalCost(19, 31, 1.2));
console.log(totalCost(45, 27, 1.15));

/**
 * Output
 *
 * 60
 * 82.8
 */

依存関係の管理

Denoでは、外部モジュールがローカルモジュールに直接インポートされるため、パッケージマネージャーの概念はありません。これは、パッケージマネージャーなしでリモートの依存関係を管理する方法の問題を提起します。依存関係の多い大きなプロジェクトでは、モジュールを個別のモジュールに個別にインポートすると、モジュールを更新するのが面倒で時間がかかります。

Denoでこの問題を解決するための標準的な方法は、deps.tsファイルを作成することです。必要なすべてのリモート依存関係がこのファイルで参照され、必要なメソッドとクラスが再エクスポートされます。依存するローカルモジュールは、リモートの依存関係ではなくdeps.tsを参照します。

これにより、大規模なコードベース全体のモジュールを簡単に更新できるようになり、「パッケージマネージャーの問題」があったとしても、それが解決されます。開発の依存関係は、別のdev_deps.tsファイルで管理することもできます。

deps.ts 例

/**
 * deps.ts re-exports the required methods from the remote Ramda module.
 **/
export {
  add,
  multiply,
} from "https://x.nest.land/ramda@0.27.0/source/index.js";

この例では、ローカルおよびリモートのインポート例と同じ機能が作成されます。ただし、この場合、Ramdaモジュールが直接参照される代わりに、ローカルのdeps.tsモジュールを使用してプロキシによって参照されます。

Command: deno run dependencies.ts

import {
  add,
  multiply,
} from "./deps.ts";

function totalCost(outbound: number, inbound: number, tax: number): number {
  return multiply(add(outbound, inbound), tax);
}

console.log(totalCost(19, 31, 1.2));
console.log(totalCost(45, 27, 1.15));

/**
 * Output
 *
 * 60
 * 82.8
 */

Unixの"cat"プログラムの実装

このプログラムでは、各コマンドライン引数はファイル名であると想定され、ファイルが開かれ、標準出力に出力されます。

const filenames = Deno.args;
for (const filename of filenames) {
  const file = await Deno.open(filename);
  await Deno.copy(file, Deno.stdout);
  file.close();
}

ここのcopy()関数は、実際には必要なカーネル->ユーザースペース->カーネルのコピーしか作成しません。つまり、データがファイルから読み取られるのと同じメモリがstdoutに書き込まれます。これは、Denoの I/Oストリームの一般的な設計目標を示しています。

プログラムを試してください:

deno run --allow-read https://deno.land/std@0.65.0/examples/cat.ts /etc/passwd

ファイルサーバー

これはHTTPでローカルディレクトリを提供します。

deno install --allow-net --allow-read https://deno.land/std@0.65.0/http/file_server.ts

それを実行します:

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

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

file_server --reload

TCP echo server

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

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エラーがスローされます。

$ deno run https://deno.land/std@0.65.0/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は明示的な許可なしにプログラムがネットワークにアクセスすることを許可していません。ネットワークへのアクセスを許可するには、コマンドラインフラグを使用します:

$ deno run --allow-net https://deno.land/std@0.65.0/examples/echo_server.ts

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

$ nc localhost 8080
hello world
hello world

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

サブプロセスを実行する

API リファレンス

例:

// create subprocess
const p = Deno.run({
  cmd: ["echo", "hello"],
});

// await its completion
await p.status();

実行:

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

ここでは、window.onloadに関数が割り当てられています。この関数は、メインスクリプトが読み込まれた後に呼び出されます。これはブラウザのonloadと同じであり、メインのエントリポイントとして使用できます。

デフォルトでは、Deno.run()を使用すると、サブプロセスは親プロセスのstdin、stdout、およびstderrを継承します。開始されたサブプロセスと通信したい場合は、"piped"オプションを使用できます。

const fileNames = Deno.args;

const p = Deno.run({
  cmd: [
    "deno",
    "run",
    "--allow-read",
    "https://deno.land/std@0.65.0/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);

実行:

$ 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)

パーミッションの調査と取り消し

このプログラムは、不安定なDeno機能を利用しています。 不安定な機能の詳細をご覧ください。

プログラムによっては、以前に付与されたアクセス許可を取り消すことが必要な場合があります。後の段階でプログラムがこれらのパーミッションを必要とする場合、プログラムは失敗します。

// lookup a permission
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", { write: true, append: true });

// revoke some permissions
await Deno.permissions.revoke({ name: "read" });
await Deno.permissions.revoke({ name: "write" });

// use the log file
const encoder = new TextEncoder();
await log.write(encoder.encode("hello\n"));

// this will fail.
await Deno.remove("request.log");

OSシグナル

このプログラムは、不安定なDeno機能を利用しています。 不安定な機能の詳細をご覧ください。

API リファレンス

Deno.signal()を使用して、OSシグナルを処理できます。

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

Deno.signal() もpromiseとして機能します。

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

シグナルの監視を停止したい場合は、シグナルオブジェクトのdispose()メソッドを使用できます。

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

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

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

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

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

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

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

  • Linux: inotify
  • macOS: FSEvents
  • Windows: ReadDirectoryChangesW

現在のファイルがメインプログラムかどうかのテスト

現在のスクリプトがプログラムへのメイン入力として実行されたかどうかをテストするには、import.meta.mainを確認します。

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