mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
Support loading additional TS lib files (#3863)
Fixes #3726 This PR provides support for referencing other lib files (like lib.dom.d.ts that are not used by default in Deno.
This commit is contained in:
parent
3d5bed35e0
commit
046bbb2691
22 changed files with 284 additions and 67 deletions
|
@ -14,13 +14,12 @@ fn op_fetch_asset(
|
|||
) -> impl Fn(&[u8], Option<ZeroCopyBuf>) -> CoreOp {
|
||||
move |control: &[u8], zero_copy_buf: Option<ZeroCopyBuf>| -> CoreOp {
|
||||
assert!(zero_copy_buf.is_none()); // zero_copy_buf unused in this op.
|
||||
let custom_assets = custom_assets.clone();
|
||||
let name = std::str::from_utf8(control).unwrap();
|
||||
|
||||
let asset_code = if let Some(source_code) = deno_typescript::get_asset(name)
|
||||
{
|
||||
source_code.to_string()
|
||||
} else if let Some(asset_path) = custom_assets.get(name) {
|
||||
} else if let Some(asset_path) = custom_assets.clone().get(name) {
|
||||
let source_code_vec =
|
||||
std::fs::read(&asset_path).expect("Asset not found");
|
||||
let source_code = std::str::from_utf8(&source_code_vec).unwrap();
|
||||
|
|
|
@ -165,7 +165,7 @@ impl SourceFileFetcher {
|
|||
maybe_referrer: Option<ModuleSpecifier>,
|
||||
) -> Pin<Box<SourceFileFuture>> {
|
||||
let module_url = specifier.as_url().to_owned();
|
||||
debug!("fetch_source_file. specifier {} ", &module_url);
|
||||
debug!("fetch_source_file_async specifier: {} ", &module_url);
|
||||
|
||||
// Check if this file was already fetched and can be retrieved from in-process cache.
|
||||
if let Some(source_file) = self.source_file_cache.get(specifier.to_string())
|
||||
|
@ -368,18 +368,13 @@ impl SourceFileFetcher {
|
|||
}
|
||||
Ok(c) => c,
|
||||
};
|
||||
let media_type = map_content_type(
|
||||
&filepath,
|
||||
source_code_headers.mime_type.as_ref().map(String::as_str),
|
||||
);
|
||||
let media_type =
|
||||
map_content_type(&filepath, source_code_headers.mime_type.as_deref());
|
||||
let types_url = match media_type {
|
||||
msg::MediaType::JavaScript | msg::MediaType::JSX => get_types_url(
|
||||
&module_url,
|
||||
&source_code,
|
||||
source_code_headers
|
||||
.x_typescript_types
|
||||
.as_ref()
|
||||
.map(String::as_str),
|
||||
source_code_headers.x_typescript_types.as_deref(),
|
||||
),
|
||||
_ => None,
|
||||
};
|
||||
|
@ -515,17 +510,13 @@ impl SourceFileFetcher {
|
|||
.location
|
||||
.join(dir.deps_cache.get_cache_filename(&module_url));
|
||||
|
||||
let media_type = map_content_type(
|
||||
&filepath,
|
||||
maybe_content_type.as_ref().map(String::as_str),
|
||||
);
|
||||
let media_type =
|
||||
map_content_type(&filepath, maybe_content_type.as_deref());
|
||||
|
||||
let types_url = match media_type {
|
||||
msg::MediaType::JavaScript | msg::MediaType::JSX => get_types_url(
|
||||
&module_url,
|
||||
&source,
|
||||
x_typescript_types.as_ref().map(String::as_str),
|
||||
),
|
||||
msg::MediaType::JavaScript | msg::MediaType::JSX => {
|
||||
get_types_url(&module_url, &source, x_typescript_types.as_deref())
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
|
|
@ -101,6 +101,10 @@ export interface CompilerOptions {
|
|||
* Does not apply to `"esnext"` target. */
|
||||
useDefineForClassFields?: boolean;
|
||||
|
||||
/** List of library files to be included in the compilation. If omitted,
|
||||
* then the Deno main runtime libs are used. */
|
||||
lib?: string[];
|
||||
|
||||
/** The locale to use to show error messages. */
|
||||
locale?: string;
|
||||
|
||||
|
|
|
@ -46,6 +46,22 @@ test(async function compilerApiCompileOptions() {
|
|||
assert(actual["/foo.js"].startsWith("define("));
|
||||
});
|
||||
|
||||
test(async function compilerApiCompileLib() {
|
||||
const [diagnostics, actual] = await compile(
|
||||
"/foo.ts",
|
||||
{
|
||||
"/foo.ts": `console.log(document.getElementById("foo"));
|
||||
console.log(Deno.args);`
|
||||
},
|
||||
{
|
||||
lib: ["dom", "es2018", "deno.ns"]
|
||||
}
|
||||
);
|
||||
assert(diagnostics == null);
|
||||
assert(actual);
|
||||
assertEquals(Object.keys(actual), ["/foo.js.map", "/foo.js"]);
|
||||
});
|
||||
|
||||
test(async function transpileOnlyApi() {
|
||||
const actual = await transpileOnly({
|
||||
"foo.ts": `export enum Foo { Foo, Bar, Baz };\n`
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { ASSETS, CompilerHostTarget, Host } from "./compiler_host.ts";
|
||||
import { CompilerHostTarget, Host } from "./compiler_host.ts";
|
||||
import { ASSETS } from "./compiler_sourcefile.ts";
|
||||
import { getAsset } from "./compiler_util.ts";
|
||||
|
||||
// NOTE: target doesn't really matter here,
|
||||
|
@ -14,18 +15,11 @@ const options = host.getCompilationSettings();
|
|||
|
||||
// This is a hacky way of adding our libs to the libs available in TypeScript()
|
||||
// as these are internal APIs of TypeScript which maintain valid libs
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
(ts as any).libs.push(
|
||||
"deno_ns",
|
||||
"deno_window",
|
||||
"deno_worker",
|
||||
"deno_shared_globals"
|
||||
);
|
||||
(ts as any).libMap.set("deno_ns", "lib.deno.ns.d.ts");
|
||||
(ts as any).libMap.set("deno_window", "lib.deno.window.d.ts");
|
||||
(ts as any).libMap.set("deno_worker", "lib.deno.worker.d.ts");
|
||||
(ts as any).libMap.set("deno_shared_globals", "lib.deno.shared_globals.d.ts");
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
ts.libs.push("deno.ns", "deno.window", "deno.worker", "deno.shared_globals");
|
||||
ts.libMap.set("deno.ns", "lib.deno.ns.d.ts");
|
||||
ts.libMap.set("deno.window", "lib.deno.window.d.ts");
|
||||
ts.libMap.set("deno.worker", "lib.deno.worker.d.ts");
|
||||
ts.libMap.set("deno.shared_globals", "lib.deno.shared_globals.d.ts");
|
||||
|
||||
// this pre-populates the cache at snapshot time of our library files, so they
|
||||
// are available in the future when needed.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { MediaType, SourceFile } from "./compiler_sourcefile.ts";
|
||||
import { ASSETS, MediaType, SourceFile } from "./compiler_sourcefile.ts";
|
||||
import { OUT_DIR, WriteFileCallback, getAsset } from "./compiler_util.ts";
|
||||
import { cwd } from "./dir.ts";
|
||||
import { assert, notImplemented } from "./util.ts";
|
||||
|
@ -18,8 +18,14 @@ export enum CompilerHostTarget {
|
|||
}
|
||||
|
||||
export interface CompilerHostOptions {
|
||||
/** Flag determines if the host should assume a single bundle output. */
|
||||
bundle?: boolean;
|
||||
|
||||
/** Determines what the default library that should be used when type checking
|
||||
* TS code. */
|
||||
target: CompilerHostTarget;
|
||||
|
||||
/** A function to be used when the program emit occurs to write out files. */
|
||||
writeFile: WriteFileCallback;
|
||||
}
|
||||
|
||||
|
@ -28,8 +34,6 @@ export interface ConfigureResponse {
|
|||
diagnostics?: ts.Diagnostic[];
|
||||
}
|
||||
|
||||
export const ASSETS = "$asset$";
|
||||
|
||||
/** Options that need to be used when generating a bundle (either trusted or
|
||||
* runtime). */
|
||||
export const defaultBundlerOptions: ts.CompilerOptions = {
|
||||
|
@ -96,7 +100,6 @@ const ignoredCompilerOptions: readonly string[] = [
|
|||
"inlineSources",
|
||||
"init",
|
||||
"isolatedModules",
|
||||
"lib",
|
||||
"listEmittedFiles",
|
||||
"listFiles",
|
||||
"mapRoot",
|
||||
|
@ -141,7 +144,10 @@ export class Host implements ts.CompilerHost {
|
|||
private _writeFile: WriteFileCallback;
|
||||
|
||||
private _getAsset(filename: string): SourceFile {
|
||||
const url = filename.split("/").pop()!;
|
||||
const lastSegment = filename.split("/").pop()!;
|
||||
const url = ts.libMap.has(lastSegment)
|
||||
? ts.libMap.get(lastSegment)!
|
||||
: lastSegment;
|
||||
const sourceFile = SourceFile.get(url);
|
||||
if (sourceFile) {
|
||||
return sourceFile;
|
||||
|
@ -150,7 +156,7 @@ export class Host implements ts.CompilerHost {
|
|||
const sourceCode = getAsset(name);
|
||||
return new SourceFile({
|
||||
url,
|
||||
filename,
|
||||
filename: `${ASSETS}/${name}`,
|
||||
mediaType: MediaType.TypeScript,
|
||||
sourceCode
|
||||
});
|
||||
|
@ -230,6 +236,7 @@ export class Host implements ts.CompilerHost {
|
|||
}
|
||||
|
||||
getDefaultLibFileName(_options: ts.CompilerOptions): string {
|
||||
util.log("compiler::host.getDefaultLibFileName()");
|
||||
switch (this._target) {
|
||||
case CompilerHostTarget.Main:
|
||||
case CompilerHostTarget.Runtime:
|
||||
|
@ -259,7 +266,7 @@ export class Host implements ts.CompilerHost {
|
|||
if (!sourceFile.tsSourceFile) {
|
||||
assert(sourceFile.sourceCode != null);
|
||||
sourceFile.tsSourceFile = ts.createSourceFile(
|
||||
fileName,
|
||||
fileName.startsWith(ASSETS) ? sourceFile.filename : fileName,
|
||||
sourceFile.sourceCode,
|
||||
languageVersion
|
||||
);
|
||||
|
|
|
@ -26,6 +26,8 @@ export interface SourceFileJson {
|
|||
sourceCode: string;
|
||||
}
|
||||
|
||||
export const ASSETS = "$asset$";
|
||||
|
||||
/** Returns the TypeScript Extension enum for a given media type. */
|
||||
function getExtension(fileName: string, mediaType: MediaType): ts.Extension {
|
||||
switch (mediaType) {
|
||||
|
@ -109,7 +111,7 @@ export class SourceFile {
|
|||
this.processed = true;
|
||||
const files = (this.importedFiles = [] as Array<[string, string]>);
|
||||
|
||||
function process(references: ts.FileReference[]): void {
|
||||
function process(references: Array<{ fileName: string }>): void {
|
||||
for (const { fileName } of references) {
|
||||
files.push([fileName, fileName]);
|
||||
}
|
||||
|
@ -133,7 +135,15 @@ export class SourceFile {
|
|||
process(importedFiles);
|
||||
}
|
||||
process(referencedFiles);
|
||||
process(libReferenceDirectives);
|
||||
// built in libs comes across as `"dom"` for example, and should be filtered
|
||||
// out during pre-processing as they are either already cached or they will
|
||||
// be lazily fetched by the compiler host. Ones that contain full files are
|
||||
// not filtered out and will be fetched as normal.
|
||||
process(
|
||||
libReferenceDirectives.filter(
|
||||
({ fileName }) => !ts.libMap.has(fileName.toLowerCase())
|
||||
)
|
||||
);
|
||||
process(typeReferenceDirectives);
|
||||
return files;
|
||||
}
|
||||
|
|
|
@ -92,15 +92,19 @@ function cache(
|
|||
}
|
||||
|
||||
let OP_FETCH_ASSET: number;
|
||||
const encoder = new TextEncoder();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
/**
|
||||
* This op is called only during snapshotting.
|
||||
*
|
||||
* We really don't want to depend on JSON dispatch
|
||||
* during snapshotting, so this op exchanges strings with Rust
|
||||
* as raw byte arrays.
|
||||
*/
|
||||
/** Retrieve an asset from Rust. */
|
||||
export function getAsset(name: string): string {
|
||||
// this path should only be called for assets that are lazily loaded at
|
||||
// runtime
|
||||
if (dispatch.OP_FETCH_ASSET) {
|
||||
util.log("compiler_util::getAsset", name);
|
||||
return sendSync(dispatch.OP_FETCH_ASSET, { name }).sourceCode;
|
||||
}
|
||||
|
||||
// this path should only be taken during snapshotting
|
||||
if (!OP_FETCH_ASSET) {
|
||||
const ops = core.ops();
|
||||
const opFetchAsset = ops["fetch_asset"];
|
||||
|
@ -108,8 +112,8 @@ export function getAsset(name: string): string {
|
|||
OP_FETCH_ASSET = opFetchAsset;
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
const decoder = new TextDecoder();
|
||||
// We really don't want to depend on JSON dispatch during snapshotting, so
|
||||
// this op exchanges strings with Rust as raw byte arrays.
|
||||
const sourceCodeBytes = core.dispatch(OP_FETCH_ASSET, encoder.encode(name));
|
||||
return decoder.decode(sourceCodeBytes!);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ export let OP_APPLY_SOURCE_MAP: number;
|
|||
export let OP_FORMAT_ERROR: number;
|
||||
export let OP_CACHE: number;
|
||||
export let OP_RESOLVE_MODULES: number;
|
||||
export let OP_FETCH_ASSET: number;
|
||||
export let OP_FETCH_SOURCE_FILES: number;
|
||||
export let OP_OPEN: number;
|
||||
export let OP_CLOSE: number;
|
||||
|
@ -76,10 +77,6 @@ export let OP_SIGNAL_BIND: number;
|
|||
export let OP_SIGNAL_UNBIND: number;
|
||||
export let OP_SIGNAL_POLL: number;
|
||||
|
||||
/** **WARNING:** This is only available during the snapshotting process and is
|
||||
* unavailable at runtime. */
|
||||
export let OP_FETCH_ASSET: number;
|
||||
|
||||
const PLUGIN_ASYNC_HANDLER_MAP: Map<number, AsyncHandler> = new Map();
|
||||
|
||||
export function setPluginAsyncHandler(
|
||||
|
|
4
cli/js/lib.deno.ns.d.ts
vendored
4
cli/js/lib.deno.ns.d.ts
vendored
|
@ -1917,6 +1917,10 @@ declare namespace Deno {
|
|||
* Does not apply to `"esnext"` target. */
|
||||
useDefineForClassFields?: boolean;
|
||||
|
||||
/** List of library files to be included in the compilation. If omitted,
|
||||
* then the Deno main runtime libs are used. */
|
||||
lib?: string[];
|
||||
|
||||
/** The locale to use to show error messages. */
|
||||
locale?: string;
|
||||
|
||||
|
|
5
cli/js/lib.deno.shared_globals.d.ts
vendored
5
cli/js/lib.deno.shared_globals.d.ts
vendored
|
@ -3,7 +3,10 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
|
||||
|
||||
/// <reference no-default-lib="true" />
|
||||
/// <reference lib="deno_ns" />
|
||||
// TODO: we need to remove this, but Fetch::Response::Body implements Reader
|
||||
// which requires Deno.EOF, and we shouldn't be leaking that, but https_proxy
|
||||
// at the least requires the Reader interface on Body, which it shouldn't
|
||||
/// <reference lib="deno.ns" />
|
||||
/// <reference lib="esnext" />
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
|
||||
|
|
4
cli/js/lib.deno.window.d.ts
vendored
4
cli/js/lib.deno.window.d.ts
vendored
|
@ -3,8 +3,8 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
|
||||
|
||||
/// <reference no-default-lib="true" />
|
||||
/// <reference lib="deno_ns" />
|
||||
/// <reference lib="deno_shared_globals" />
|
||||
/// <reference lib="deno.ns" />
|
||||
/// <reference lib="deno.shared_globals" />
|
||||
/// <reference lib="esnext" />
|
||||
|
||||
declare interface Window extends WindowOrWorkerGlobalScope {
|
||||
|
|
2
cli/js/lib.deno.worker.d.ts
vendored
2
cli/js/lib.deno.worker.d.ts
vendored
|
@ -3,7 +3,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
|
||||
|
||||
/// <reference no-default-lib="true" />
|
||||
/// <reference lib="deno_shared_globals" />
|
||||
/// <reference lib="deno.shared_globals" />
|
||||
/// <reference lib="esnext" />
|
||||
|
||||
declare interface DedicatedWorkerGlobalScope extends WindowOrWorkerGlobalScope {
|
||||
|
|
7
cli/js/ts_global.d.ts
vendored
7
cli/js/ts_global.d.ts
vendored
|
@ -16,4 +16,11 @@ declare global {
|
|||
namespace ts {
|
||||
export = ts_;
|
||||
}
|
||||
|
||||
namespace ts {
|
||||
// this are marked @internal in TypeScript, but we need to access them,
|
||||
// there is a risk these could change in future versions of TypeScript
|
||||
export const libs: string[];
|
||||
export const libMap: Map<string, string>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
use super::dispatch_json::{Deserialize, JsonOp, Value};
|
||||
use super::dispatch_json::Deserialize;
|
||||
use super::dispatch_json::JsonOp;
|
||||
use super::dispatch_json::Value;
|
||||
use crate::futures::future::try_join_all;
|
||||
use crate::msg;
|
||||
use crate::ops::json_op;
|
||||
|
@ -17,6 +19,10 @@ pub fn init(i: &mut Isolate, s: &State) {
|
|||
"fetch_source_files",
|
||||
s.core_op(json_op(s.stateful_op(op_fetch_source_files))),
|
||||
);
|
||||
i.register_op(
|
||||
"fetch_asset",
|
||||
s.core_op(json_op(s.stateful_op(op_fetch_asset))),
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -154,3 +160,26 @@ fn op_fetch_source_files(
|
|||
|
||||
Ok(JsonOp::Async(future))
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct FetchRemoteAssetArgs {
|
||||
name: String,
|
||||
}
|
||||
|
||||
fn op_fetch_asset(
|
||||
_state: &State,
|
||||
args: Value,
|
||||
_data: Option<ZeroCopyBuf>,
|
||||
) -> Result<JsonOp, ErrBox> {
|
||||
let args: FetchRemoteAssetArgs = serde_json::from_value(args)?;
|
||||
debug!("args.name: {}", args.name);
|
||||
|
||||
let source_code =
|
||||
if let Some(source_code) = deno_typescript::get_asset(&args.name) {
|
||||
source_code.to_string()
|
||||
} else {
|
||||
panic!("Asset not found: \"{}\"", args.name)
|
||||
};
|
||||
|
||||
Ok(JsonOp::Sync(json!({ "sourceCode": source_code })))
|
||||
}
|
||||
|
|
|
@ -833,6 +833,16 @@ itest!(import_meta {
|
|||
output: "import_meta.ts.out",
|
||||
});
|
||||
|
||||
itest!(lib_ref {
|
||||
args: "run --reload lib_ref.ts",
|
||||
output: "lib_ref.ts.out",
|
||||
});
|
||||
|
||||
itest!(lib_runtime_api {
|
||||
args: "run --reload lib_runtime_api.ts",
|
||||
output: "lib_runtime_api.ts.out",
|
||||
});
|
||||
|
||||
itest!(seed_random {
|
||||
args: "run --seed=100 seed_random.js",
|
||||
output: "seed_random.js.out",
|
||||
|
|
13
cli/tests/lib_ref.ts
Normal file
13
cli/tests/lib_ref.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
const [errors, program] = await Deno.compile(
|
||||
"main.ts",
|
||||
{
|
||||
"main.ts": `/// <reference lib="dom" />\n\ndocument.getElementById("foo");\nDeno.args;`
|
||||
},
|
||||
{
|
||||
target: "es2018",
|
||||
lib: ["es2018", "deno.ns"]
|
||||
}
|
||||
);
|
||||
|
||||
console.log(errors);
|
||||
console.log(Object.keys(program));
|
2
cli/tests/lib_ref.ts.out
Normal file
2
cli/tests/lib_ref.ts.out
Normal file
|
@ -0,0 +1,2 @@
|
|||
null
|
||||
[ "main.js.map", "main.js" ]
|
12
cli/tests/lib_runtime_api.ts
Normal file
12
cli/tests/lib_runtime_api.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
const [errors, program] = await Deno.compile(
|
||||
"main.ts",
|
||||
{
|
||||
"main.ts": `document.getElementById("foo");`
|
||||
},
|
||||
{
|
||||
lib: ["dom", "esnext"]
|
||||
}
|
||||
);
|
||||
|
||||
console.log(errors);
|
||||
console.log(Object.keys(program));
|
2
cli/tests/lib_runtime_api.ts.out
Normal file
2
cli/tests/lib_runtime_api.ts.out
Normal file
|
@ -0,0 +1,2 @@
|
|||
null
|
||||
[ "main.js.map", "main.js" ]
|
|
@ -248,36 +248,44 @@ pub fn get_asset(name: &str) -> Option<&'static str> {
|
|||
"system_loader.js" => Some(include_str!("system_loader.js")),
|
||||
"bootstrap.ts" => Some("console.log(\"hello deno\");"),
|
||||
"typescript.d.ts" => inc!("typescript.d.ts"),
|
||||
"lib.dom.d.ts" => inc!("lib.dom.d.ts"),
|
||||
"lib.dom.iterable.d.ts" => inc!("lib.dom.d.ts"),
|
||||
"lib.es5.d.ts" => inc!("lib.es5.d.ts"),
|
||||
"lib.es6.d.ts" => inc!("lib.es6.d.ts"),
|
||||
"lib.esnext.d.ts" => inc!("lib.esnext.d.ts"),
|
||||
"lib.es2020.d.ts" => inc!("lib.es2020.d.ts"),
|
||||
"lib.es2020.full.d.ts" => inc!("lib.es2020.full.d.ts"),
|
||||
"lib.es2019.d.ts" => inc!("lib.es2019.d.ts"),
|
||||
"lib.es2019.full.d.ts" => inc!("lib.es2019.full.d.ts"),
|
||||
"lib.es2018.d.ts" => inc!("lib.es2018.d.ts"),
|
||||
"lib.es2018.full.d.ts" => inc!("lib.es2018.full.d.ts"),
|
||||
"lib.es2017.d.ts" => inc!("lib.es2017.d.ts"),
|
||||
"lib.es2017.full.d.ts" => inc!("lib.es2017.full.d.ts"),
|
||||
"lib.es2016.d.ts" => inc!("lib.es2016.d.ts"),
|
||||
"lib.es5.d.ts" => inc!("lib.es5.d.ts"),
|
||||
"lib.es2016.full.d.ts" => inc!("lib.es2016.full.d.ts"),
|
||||
"lib.es2015.d.ts" => inc!("lib.es2015.d.ts"),
|
||||
"lib.es2015.core.d.ts" => inc!("lib.es2015.core.d.ts"),
|
||||
"lib.es2015.collection.d.ts" => inc!("lib.es2015.collection.d.ts"),
|
||||
"lib.es2015.core.d.ts" => inc!("lib.es2015.core.d.ts"),
|
||||
"lib.es2015.generator.d.ts" => inc!("lib.es2015.generator.d.ts"),
|
||||
"lib.es2015.iterable.d.ts" => inc!("lib.es2015.iterable.d.ts"),
|
||||
"lib.es2015.promise.d.ts" => inc!("lib.es2015.promise.d.ts"),
|
||||
"lib.es2015.symbol.d.ts" => inc!("lib.es2015.symbol.d.ts"),
|
||||
"lib.es2015.proxy.d.ts" => inc!("lib.es2015.proxy.d.ts"),
|
||||
"lib.es2015.reflect.d.ts" => inc!("lib.es2015.reflect.d.ts"),
|
||||
"lib.es2015.symbol.d.ts" => inc!("lib.es2015.symbol.d.ts"),
|
||||
"lib.es2015.symbol.wellknown.d.ts" => {
|
||||
inc!("lib.es2015.symbol.wellknown.d.ts")
|
||||
}
|
||||
"lib.es2015.reflect.d.ts" => inc!("lib.es2015.reflect.d.ts"),
|
||||
"lib.es2016.array.include.d.ts" => inc!("lib.es2016.array.include.d.ts"),
|
||||
"lib.es2017.intl.d.ts" => inc!("lib.es2017.intl.d.ts"),
|
||||
"lib.es2017.object.d.ts" => inc!("lib.es2017.object.d.ts"),
|
||||
"lib.es2017.sharedmemory.d.ts" => inc!("lib.es2017.sharedmemory.d.ts"),
|
||||
"lib.es2017.string.d.ts" => inc!("lib.es2017.string.d.ts"),
|
||||
"lib.es2017.intl.d.ts" => inc!("lib.es2017.intl.d.ts"),
|
||||
"lib.es2017.typedarrays.d.ts" => inc!("lib.es2017.typedarrays.d.ts"),
|
||||
"lib.es2018.asyncgenerator.d.ts" => inc!("lib.es2018.asyncgenerator.d.ts"),
|
||||
"lib.es2018.asynciterable.d.ts" => inc!("lib.es2018.asynciterable.d.ts"),
|
||||
"lib.es2018.intl.d.ts" => inc!("lib.es2018.intl.d.ts"),
|
||||
"lib.es2018.promise.d.ts" => inc!("lib.es2018.promise.d.ts"),
|
||||
"lib.es2018.regexp.d.ts" => inc!("lib.es2018.regexp.d.ts"),
|
||||
"lib.es2018.intl.d.ts" => inc!("lib.es2018.intl.d.ts"),
|
||||
"lib.es2019.array.d.ts" => inc!("lib.es2019.array.d.ts"),
|
||||
"lib.es2019.object.d.ts" => inc!("lib.es2019.object.d.ts"),
|
||||
"lib.es2019.string.d.ts" => inc!("lib.es2019.string.d.ts"),
|
||||
|
@ -291,6 +299,11 @@ pub fn get_asset(name: &str) -> Option<&'static str> {
|
|||
"lib.esnext.bigint.d.ts" => inc!("lib.esnext.bigint.d.ts"),
|
||||
"lib.esnext.intl.d.ts" => inc!("lib.esnext.intl.d.ts"),
|
||||
"lib.esnext.symbol.d.ts" => inc!("lib.esnext.symbol.d.ts"),
|
||||
"lib.scripthost.d.ts" => inc!("lib.scripthost.d.ts"),
|
||||
"lib.webworker.d.ts" => inc!("lib.webworker.d.ts"),
|
||||
"lib.webworker.importscripts.d.ts" => {
|
||||
inc!("lib.webworker.importscripts.d.ts")
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
100
std/manual.md
100
std/manual.md
|
@ -174,6 +174,12 @@ command line:
|
|||
$ deno types
|
||||
```
|
||||
|
||||
The output is the concatenation of three library files that are built into Deno:
|
||||
|
||||
- [lib.deno.ns.d.ts](https://github.com/denoland/deno/blob/master/cli/js/lib.deno.ns.d.ts)
|
||||
- [lib.deno.shared_globals.d.ts](https://github.com/denoland/deno/blob/master/cli/js/lib.deno.shared_globals.d.ts)
|
||||
- [lib.deno.window.d.ts](https://github.com/denoland/deno/blob/master/cli/js/lib.deno.window.d.ts)
|
||||
|
||||
[This is what the output looks like.](https://github.com/denoland/deno/blob/master/cli/js/lib.deno_runtime.d.ts)
|
||||
|
||||
### Reference websites
|
||||
|
@ -640,6 +646,100 @@ reference directive. If Deno used this, it would interfere with the behavior of
|
|||
the TypeScript compiler. Deno only looks for the directive in JavaScript (and
|
||||
JSX) files.
|
||||
|
||||
### 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. In order 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:
|
||||
|
||||
```ts
|
||||
const [errors, emitted] = 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](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
|
||||
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 the `Deno` 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:
|
||||
|
||||
```ts
|
||||
const [errors, emitted] = 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 just the compiler options. Deno supports
|
||||
[the triple-slash reference to a lib](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-lib-).
|
||||
and could be embedded in the contents of the file. For example of you have a
|
||||
`main.ts` like:
|
||||
|
||||
```ts
|
||||
/// <reference lib="dom" />
|
||||
|
||||
document.getElementById("foo");
|
||||
```
|
||||
|
||||
It would compiler without errors like this:
|
||||
|
||||
```ts
|
||||
const [errors, emitted] = 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.
|
||||
|
||||
### Testing if current file is the main program
|
||||
|
||||
To test if the current script has been executed as the main input to the program
|
||||
|
|
Loading…
Reference in a new issue