Skip to content

Commit

Permalink
Runtime Compiler API (denoland/deno#3442)
Browse files Browse the repository at this point in the history
Also restructures the compiler TypeScript files to make them easier to
manage and eventually integrate deno_typescript fully.
  • Loading branch information
kitsonk authored and denobot committed Feb 1, 2021
1 parent 8c250d5 commit c5ffa6c
Showing 1 changed file with 126 additions and 0 deletions.
126 changes: 126 additions & 0 deletions manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,132 @@ import { fib } from "./fib.wasm";
console.log(fib(20));
```

## Compiler API

Deno supports runtime access to the built in TypeScript compiler. There are
three methods in the `Deno` namespace that provide this access.

### `Deno.compile()`

This works similar to `deno fetch` in that it can fetch code, compile it, but
not run it. 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 --reload run 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. 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
which can be supported by Deno.

The method resolves with a tuple where the first argument is any diagnostics
(syntax or type errors) related to the code, and a map of the code, where the
key would be the output filename and the value would be the content.

An example of providing sources:

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

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

We would expect map to contain 4 "files", named `/foo.js.map`, `/foo.js`,
`/bar.js.map`, and `/bar.js`.

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:

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

We should get back in the `emitMap` a simple `console.log()` statement.

### `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. 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
which can be supported by Deno.

An example of providing sources:

```ts
const [diagnostics, emit] = 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(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:

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

We should get back in `emit` 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 contents.
The only purpose of the module name is when putting information into a source
map, of what the source file name was. The second is optionally `options` which
is of type `Deno.CompilerOptions`. This is a subset of options which can be
supported by Deno. It resolves with a map where the key is the source module
name supplied, and the value is an object with a property of `source` which is
the output contents of the module, and optionally `map` which would be the
source map. By default, source maps are output, but can be turned off via the
`options` argument.

An example:

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

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

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

## Program lifecycle

Deno supports browser compatible lifecycle events: `load` and `unload`. You can
Expand Down

0 comments on commit c5ffa6c

Please sign in to comment.