コンパイラ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オプションを指定する必要があります。