コンパイラ API
この API は unstable です。詳細は以下。 unstable features.
Deno は組み込みの TypeScript コンパイラにアクセスするランタイムをサポートしています。 Deno
名前空間にはこのアクセスを提供する3つのメソッドがあります。
Deno.compile()
これは deno cache
と似て、コードをフェッチし、キャッシュし、コンパイルしますが、実行はしません。 引数は3つまで与えることができます。rootName
が必須で、sources
は任意、options
は任意です。 rootName
はプログラムの生成に使われるルートモジュールです。これはコマンドラインの deno run --reload example.ts
で渡すモジュール名と同様です。 sources
はハッシュで、キーはモジュールの完全修飾名、値はモジュールのテキストソースになります。 sources
が渡されると、Deno はすべてのモジュールをそのハッシュから解決し、Deno の外部にモジュール解決を試みなくなります。 sources
が与えられない場合、Deno はルートモジュールがコマンドラインで渡されるときと同じ方法でモジュール解決を行います。 また、Deno はこれらのリソースをキャッシュします。 解決されたリソースはすべて動的インポートとして扱われ、それらがローカルやリモートにある場合には読み取りやネットのパーミッションを要求します。 options
引数は Deno.CompilerOptions
型のオプションで、Deno がサポートしている機能を含む TypeScript コンパイラオプションのサブセットです。
メソッドはタプルを返します。一番目の値はコードに関する診断(構文エラーや型エラー)を含みます。 二番目の値は出力するファイル名をキーとしファイルの中身を値とするマップです。
以下はソースを与える例です。
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);
マップに4つの「ファイル」が含まれることが期待されます。ファイル名は /foo.js.map
、/foo.js
、/bar.js.map
、/bar.js
です。
リソースを与えない場合、ローカルまたはリモートのモジュールを使うことができます。 コマンドラインで使うのと同じです。たとえば以下のようにできます。
const [diagnostics, emitMap] = await Deno.compile(
"https://deno.land/std@$STD_VERSION/examples/welcome.ts",
);
この例では emitMap
は console.log()
文を含むはずです。
Deno.bundle()
This works a lot like deno bundle
does on the command line. It is also like Deno.compile()
, except instead of returning a map of files, it returns a single string, which is a self-contained JavaScript ES module which will include all of the code that was provided or resolved as well as exports of all the exports of the root module that was provided. It takes up to three arguments, the rootName
, optionally sources
, and optionally options
. The rootName
is the root module which will be used to generate the resulting program. This is like module name you would pass on the command line in deno bundle example.ts
. The sources
is a hash where the key is the fully qualified module name, and the value is the text source of the module. If sources
is passed, Deno will resolve all the modules from within that hash and not attempt to resolve them outside of Deno. If sources
are not provided, Deno will resolve modules as if the root module had been passed on the command line. All resolved resources are treated as dynamic imports and require read or net permissions depending if they're local or remote. Deno will also cache any of these resources. The options
argument is a set of options of type Deno.CompilerOptions
, which is a subset of the TypeScript compiler options containing the ones supported by Deno.
An example of providing sources:
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);
We would expect emit
to be the text for an ES module, which would contain the output sources for both modules.
When not supplying resources, you can use local or remote modules, just like you could do on the command line. So you could do something like this:
const [diagnostics, emit] = await Deno.bundle(
"https://deno.land/std@$STD_VERSION/http/server.ts",
);
In this case emit
will be a self contained JavaScript ES module with all of its dependencies resolved and exporting the same exports as the source module.
Deno.transpileOnly()
This is based off of the TypeScript function transpileModule()
. All this does is "erase" any types from the modules and emit JavaScript. There is no type checking and no resolution of dependencies. It accepts up to two arguments, the first is a hash where the key is the module name and the value is the content. The only purpose of the module name is when putting information into a source map, of what the source file name was. The second argument contains optional options
of the type Deno.CompilerOptions
. The function resolves with a map where the key is the source module name supplied, and the value is an object with a property of source
and optionally map
. The first is the output contents of the module. The map
property is the source map. Source maps are provided by default, but can be turned off via the options
argument.
An example:
const result = await Deno.transpileOnly({
"/foo.ts": `enum Foo { Foo, Bar, Baz };\n`,
});
console.log(result["/foo.ts"].source);
console.log(result["/foo.ts"].map);
We would expect the enum
would be rewritten to an IIFE which constructs the enumerable, and the map to be defined.
Referencing TypeScript library files
When you use deno run
, or other Deno commands which type check TypeScript, that code is evaluated against custom libraries which describe the environment that Deno supports. By default, the compiler runtime APIs which type check TypeScript also use these libraries (Deno.compile()
and Deno.bundle()
).
But if you want to compile or bundle TypeScript for some other runtime, you may want to override the default libraries. To do this, the runtime APIs support the lib
property in the compiler options. For example, if you had TypeScript code that is destined for the browser, you would want to use the TypeScript "dom"
library:
const [errors, emitted] = await Deno.compile(
"main.ts",
{
"main.ts": `document.getElementById("foo");\n`,
},
{
lib: ["dom", "esnext"],
},
);
For a list of all the libraries that TypeScript supports, see the lib
compiler option documentation.
Don't forget to include the JavaScript library
Just like tsc
, when you supply a lib
compiler option, it overrides the default ones, which means that the basic JavaScript library won't be included and you should include the one that best represents your target runtime (e.g. es5
, es2015
, es2016
, es2017
, es2018
, es2019
, es2020
or esnext
).
Including the Deno
namespace
In addition to the libraries that are provided by TypeScript, there are four libraries that are built into Deno that can be referenced:
deno.ns
- Provides theDeno
namespace.deno.shared_globals
- Provides global interfaces and variables which Deno supports at runtime that are then exposed by the final runtime library.deno.window
- Exposes the global variables plus the Deno namespace that are available in the Deno main worker and is the default for the runtime compiler APIs.deno.worker
- Exposes the global variables that are available in workers under Deno.
So to add the Deno namespace to a compilation, you would include the deno.ns
lib in the array. For example:
const [errors, emitted] = await Deno.compile(
"main.ts",
{
"main.ts": `document.getElementById("foo");\n`,
},
{
lib: ["dom", "esnext", "deno.ns"],
},
);
Note that the Deno namespace expects a runtime environment that is at least ES2018 or later. This means if you use a lib "lower" than ES2018 you will get errors logged as part of the compilation.
Using the triple slash reference
You do not have to specify the lib
in the compiler options. Deno also supports the triple-slash reference to a lib which can be embedded in the contents of the file. For example, if you have a main.ts
like:
/// <reference lib="dom" />
document.getElementById("foo");
It would compile without errors like this:
const [errors, emitted] = await Deno.compile("./main.ts", undefined, {
lib: ["esnext"],
});
Note that the dom
library conflicts with some of the default globals that are defined in the default type library for Deno. To avoid this, you need to specify a lib
option in the compiler options to the runtime compiler APIs.