mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -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 {
|
) -> impl Fn(&[u8], Option<ZeroCopyBuf>) -> CoreOp {
|
||||||
move |control: &[u8], zero_copy_buf: 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.
|
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 name = std::str::from_utf8(control).unwrap();
|
||||||
|
|
||||||
let asset_code = if let Some(source_code) = deno_typescript::get_asset(name)
|
let asset_code = if let Some(source_code) = deno_typescript::get_asset(name)
|
||||||
{
|
{
|
||||||
source_code.to_string()
|
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 =
|
let source_code_vec =
|
||||||
std::fs::read(&asset_path).expect("Asset not found");
|
std::fs::read(&asset_path).expect("Asset not found");
|
||||||
let source_code = std::str::from_utf8(&source_code_vec).unwrap();
|
let source_code = std::str::from_utf8(&source_code_vec).unwrap();
|
||||||
|
|
|
@ -165,7 +165,7 @@ impl SourceFileFetcher {
|
||||||
maybe_referrer: Option<ModuleSpecifier>,
|
maybe_referrer: Option<ModuleSpecifier>,
|
||||||
) -> Pin<Box<SourceFileFuture>> {
|
) -> Pin<Box<SourceFileFuture>> {
|
||||||
let module_url = specifier.as_url().to_owned();
|
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.
|
// 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())
|
if let Some(source_file) = self.source_file_cache.get(specifier.to_string())
|
||||||
|
@ -368,18 +368,13 @@ impl SourceFileFetcher {
|
||||||
}
|
}
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
};
|
};
|
||||||
let media_type = map_content_type(
|
let media_type =
|
||||||
&filepath,
|
map_content_type(&filepath, source_code_headers.mime_type.as_deref());
|
||||||
source_code_headers.mime_type.as_ref().map(String::as_str),
|
|
||||||
);
|
|
||||||
let types_url = match media_type {
|
let types_url = match media_type {
|
||||||
msg::MediaType::JavaScript | msg::MediaType::JSX => get_types_url(
|
msg::MediaType::JavaScript | msg::MediaType::JSX => get_types_url(
|
||||||
&module_url,
|
&module_url,
|
||||||
&source_code,
|
&source_code,
|
||||||
source_code_headers
|
source_code_headers.x_typescript_types.as_deref(),
|
||||||
.x_typescript_types
|
|
||||||
.as_ref()
|
|
||||||
.map(String::as_str),
|
|
||||||
),
|
),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
@ -515,17 +510,13 @@ impl SourceFileFetcher {
|
||||||
.location
|
.location
|
||||||
.join(dir.deps_cache.get_cache_filename(&module_url));
|
.join(dir.deps_cache.get_cache_filename(&module_url));
|
||||||
|
|
||||||
let media_type = map_content_type(
|
let media_type =
|
||||||
&filepath,
|
map_content_type(&filepath, maybe_content_type.as_deref());
|
||||||
maybe_content_type.as_ref().map(String::as_str),
|
|
||||||
);
|
|
||||||
|
|
||||||
let types_url = match media_type {
|
let types_url = match media_type {
|
||||||
msg::MediaType::JavaScript | msg::MediaType::JSX => get_types_url(
|
msg::MediaType::JavaScript | msg::MediaType::JSX => {
|
||||||
&module_url,
|
get_types_url(&module_url, &source, x_typescript_types.as_deref())
|
||||||
&source,
|
}
|
||||||
x_typescript_types.as_ref().map(String::as_str),
|
|
||||||
),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,10 @@ export interface CompilerOptions {
|
||||||
* Does not apply to `"esnext"` target. */
|
* Does not apply to `"esnext"` target. */
|
||||||
useDefineForClassFields?: boolean;
|
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. */
|
/** The locale to use to show error messages. */
|
||||||
locale?: string;
|
locale?: string;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,22 @@ test(async function compilerApiCompileOptions() {
|
||||||
assert(actual["/foo.js"].startsWith("define("));
|
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() {
|
test(async function transpileOnlyApi() {
|
||||||
const actual = await transpileOnly({
|
const actual = await transpileOnly({
|
||||||
"foo.ts": `export enum Foo { Foo, Bar, Baz };\n`
|
"foo.ts": `export enum Foo { Foo, Bar, Baz };\n`
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// 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";
|
import { getAsset } from "./compiler_util.ts";
|
||||||
|
|
||||||
// NOTE: target doesn't really matter here,
|
// 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()
|
// 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
|
// as these are internal APIs of TypeScript which maintain valid libs
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
ts.libs.push("deno.ns", "deno.window", "deno.worker", "deno.shared_globals");
|
||||||
(ts as any).libs.push(
|
ts.libMap.set("deno.ns", "lib.deno.ns.d.ts");
|
||||||
"deno_ns",
|
ts.libMap.set("deno.window", "lib.deno.window.d.ts");
|
||||||
"deno_window",
|
ts.libMap.set("deno.worker", "lib.deno.worker.d.ts");
|
||||||
"deno_worker",
|
ts.libMap.set("deno.shared_globals", "lib.deno.shared_globals.d.ts");
|
||||||
"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 */
|
|
||||||
|
|
||||||
// this pre-populates the cache at snapshot time of our library files, so they
|
// this pre-populates the cache at snapshot time of our library files, so they
|
||||||
// are available in the future when needed.
|
// are available in the future when needed.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// 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 { OUT_DIR, WriteFileCallback, getAsset } from "./compiler_util.ts";
|
||||||
import { cwd } from "./dir.ts";
|
import { cwd } from "./dir.ts";
|
||||||
import { assert, notImplemented } from "./util.ts";
|
import { assert, notImplemented } from "./util.ts";
|
||||||
|
@ -18,8 +18,14 @@ export enum CompilerHostTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompilerHostOptions {
|
export interface CompilerHostOptions {
|
||||||
|
/** Flag determines if the host should assume a single bundle output. */
|
||||||
bundle?: boolean;
|
bundle?: boolean;
|
||||||
|
|
||||||
|
/** Determines what the default library that should be used when type checking
|
||||||
|
* TS code. */
|
||||||
target: CompilerHostTarget;
|
target: CompilerHostTarget;
|
||||||
|
|
||||||
|
/** A function to be used when the program emit occurs to write out files. */
|
||||||
writeFile: WriteFileCallback;
|
writeFile: WriteFileCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +34,6 @@ export interface ConfigureResponse {
|
||||||
diagnostics?: ts.Diagnostic[];
|
diagnostics?: ts.Diagnostic[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ASSETS = "$asset$";
|
|
||||||
|
|
||||||
/** Options that need to be used when generating a bundle (either trusted or
|
/** Options that need to be used when generating a bundle (either trusted or
|
||||||
* runtime). */
|
* runtime). */
|
||||||
export const defaultBundlerOptions: ts.CompilerOptions = {
|
export const defaultBundlerOptions: ts.CompilerOptions = {
|
||||||
|
@ -96,7 +100,6 @@ const ignoredCompilerOptions: readonly string[] = [
|
||||||
"inlineSources",
|
"inlineSources",
|
||||||
"init",
|
"init",
|
||||||
"isolatedModules",
|
"isolatedModules",
|
||||||
"lib",
|
|
||||||
"listEmittedFiles",
|
"listEmittedFiles",
|
||||||
"listFiles",
|
"listFiles",
|
||||||
"mapRoot",
|
"mapRoot",
|
||||||
|
@ -141,7 +144,10 @@ export class Host implements ts.CompilerHost {
|
||||||
private _writeFile: WriteFileCallback;
|
private _writeFile: WriteFileCallback;
|
||||||
|
|
||||||
private _getAsset(filename: string): SourceFile {
|
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);
|
const sourceFile = SourceFile.get(url);
|
||||||
if (sourceFile) {
|
if (sourceFile) {
|
||||||
return sourceFile;
|
return sourceFile;
|
||||||
|
@ -150,7 +156,7 @@ export class Host implements ts.CompilerHost {
|
||||||
const sourceCode = getAsset(name);
|
const sourceCode = getAsset(name);
|
||||||
return new SourceFile({
|
return new SourceFile({
|
||||||
url,
|
url,
|
||||||
filename,
|
filename: `${ASSETS}/${name}`,
|
||||||
mediaType: MediaType.TypeScript,
|
mediaType: MediaType.TypeScript,
|
||||||
sourceCode
|
sourceCode
|
||||||
});
|
});
|
||||||
|
@ -230,6 +236,7 @@ export class Host implements ts.CompilerHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultLibFileName(_options: ts.CompilerOptions): string {
|
getDefaultLibFileName(_options: ts.CompilerOptions): string {
|
||||||
|
util.log("compiler::host.getDefaultLibFileName()");
|
||||||
switch (this._target) {
|
switch (this._target) {
|
||||||
case CompilerHostTarget.Main:
|
case CompilerHostTarget.Main:
|
||||||
case CompilerHostTarget.Runtime:
|
case CompilerHostTarget.Runtime:
|
||||||
|
@ -259,7 +266,7 @@ export class Host implements ts.CompilerHost {
|
||||||
if (!sourceFile.tsSourceFile) {
|
if (!sourceFile.tsSourceFile) {
|
||||||
assert(sourceFile.sourceCode != null);
|
assert(sourceFile.sourceCode != null);
|
||||||
sourceFile.tsSourceFile = ts.createSourceFile(
|
sourceFile.tsSourceFile = ts.createSourceFile(
|
||||||
fileName,
|
fileName.startsWith(ASSETS) ? sourceFile.filename : fileName,
|
||||||
sourceFile.sourceCode,
|
sourceFile.sourceCode,
|
||||||
languageVersion
|
languageVersion
|
||||||
);
|
);
|
||||||
|
|
|
@ -26,6 +26,8 @@ export interface SourceFileJson {
|
||||||
sourceCode: string;
|
sourceCode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ASSETS = "$asset$";
|
||||||
|
|
||||||
/** Returns the TypeScript Extension enum for a given media type. */
|
/** Returns the TypeScript Extension enum for a given media type. */
|
||||||
function getExtension(fileName: string, mediaType: MediaType): ts.Extension {
|
function getExtension(fileName: string, mediaType: MediaType): ts.Extension {
|
||||||
switch (mediaType) {
|
switch (mediaType) {
|
||||||
|
@ -109,7 +111,7 @@ export class SourceFile {
|
||||||
this.processed = true;
|
this.processed = true;
|
||||||
const files = (this.importedFiles = [] as Array<[string, string]>);
|
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) {
|
for (const { fileName } of references) {
|
||||||
files.push([fileName, fileName]);
|
files.push([fileName, fileName]);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +135,15 @@ export class SourceFile {
|
||||||
process(importedFiles);
|
process(importedFiles);
|
||||||
}
|
}
|
||||||
process(referencedFiles);
|
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);
|
process(typeReferenceDirectives);
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,15 +92,19 @@ function cache(
|
||||||
}
|
}
|
||||||
|
|
||||||
let OP_FETCH_ASSET: number;
|
let OP_FETCH_ASSET: number;
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
|
||||||
/**
|
/** Retrieve an asset from Rust. */
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
export function getAsset(name: string): string {
|
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) {
|
if (!OP_FETCH_ASSET) {
|
||||||
const ops = core.ops();
|
const ops = core.ops();
|
||||||
const opFetchAsset = ops["fetch_asset"];
|
const opFetchAsset = ops["fetch_asset"];
|
||||||
|
@ -108,8 +112,8 @@ export function getAsset(name: string): string {
|
||||||
OP_FETCH_ASSET = opFetchAsset;
|
OP_FETCH_ASSET = opFetchAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
const encoder = new TextEncoder();
|
// We really don't want to depend on JSON dispatch during snapshotting, so
|
||||||
const decoder = new TextDecoder();
|
// this op exchanges strings with Rust as raw byte arrays.
|
||||||
const sourceCodeBytes = core.dispatch(OP_FETCH_ASSET, encoder.encode(name));
|
const sourceCodeBytes = core.dispatch(OP_FETCH_ASSET, encoder.encode(name));
|
||||||
return decoder.decode(sourceCodeBytes!);
|
return decoder.decode(sourceCodeBytes!);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ export let OP_APPLY_SOURCE_MAP: number;
|
||||||
export let OP_FORMAT_ERROR: number;
|
export let OP_FORMAT_ERROR: number;
|
||||||
export let OP_CACHE: number;
|
export let OP_CACHE: number;
|
||||||
export let OP_RESOLVE_MODULES: number;
|
export let OP_RESOLVE_MODULES: number;
|
||||||
|
export let OP_FETCH_ASSET: number;
|
||||||
export let OP_FETCH_SOURCE_FILES: number;
|
export let OP_FETCH_SOURCE_FILES: number;
|
||||||
export let OP_OPEN: number;
|
export let OP_OPEN: number;
|
||||||
export let OP_CLOSE: 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_UNBIND: number;
|
||||||
export let OP_SIGNAL_POLL: 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();
|
const PLUGIN_ASYNC_HANDLER_MAP: Map<number, AsyncHandler> = new Map();
|
||||||
|
|
||||||
export function setPluginAsyncHandler(
|
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. */
|
* Does not apply to `"esnext"` target. */
|
||||||
useDefineForClassFields?: boolean;
|
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. */
|
/** The locale to use to show error messages. */
|
||||||
locale?: string;
|
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 */
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
/// <reference no-default-lib="true" />
|
/// <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" />
|
/// <reference lib="esnext" />
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope
|
// 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 */
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
/// <reference no-default-lib="true" />
|
/// <reference no-default-lib="true" />
|
||||||
/// <reference lib="deno_ns" />
|
/// <reference lib="deno.ns" />
|
||||||
/// <reference lib="deno_shared_globals" />
|
/// <reference lib="deno.shared_globals" />
|
||||||
/// <reference lib="esnext" />
|
/// <reference lib="esnext" />
|
||||||
|
|
||||||
declare interface Window extends WindowOrWorkerGlobalScope {
|
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 */
|
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface, @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
/// <reference no-default-lib="true" />
|
/// <reference no-default-lib="true" />
|
||||||
/// <reference lib="deno_shared_globals" />
|
/// <reference lib="deno.shared_globals" />
|
||||||
/// <reference lib="esnext" />
|
/// <reference lib="esnext" />
|
||||||
|
|
||||||
declare interface DedicatedWorkerGlobalScope extends WindowOrWorkerGlobalScope {
|
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 {
|
namespace ts {
|
||||||
export = 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.
|
// 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::futures::future::try_join_all;
|
||||||
use crate::msg;
|
use crate::msg;
|
||||||
use crate::ops::json_op;
|
use crate::ops::json_op;
|
||||||
|
@ -17,6 +19,10 @@ pub fn init(i: &mut Isolate, s: &State) {
|
||||||
"fetch_source_files",
|
"fetch_source_files",
|
||||||
s.core_op(json_op(s.stateful_op(op_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)]
|
#[derive(Deserialize)]
|
||||||
|
@ -154,3 +160,26 @@ fn op_fetch_source_files(
|
||||||
|
|
||||||
Ok(JsonOp::Async(future))
|
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",
|
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 {
|
itest!(seed_random {
|
||||||
args: "run --seed=100 seed_random.js",
|
args: "run --seed=100 seed_random.js",
|
||||||
output: "seed_random.js.out",
|
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")),
|
"system_loader.js" => Some(include_str!("system_loader.js")),
|
||||||
"bootstrap.ts" => Some("console.log(\"hello deno\");"),
|
"bootstrap.ts" => Some("console.log(\"hello deno\");"),
|
||||||
"typescript.d.ts" => inc!("typescript.d.ts"),
|
"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.esnext.d.ts" => inc!("lib.esnext.d.ts"),
|
||||||
"lib.es2020.d.ts" => inc!("lib.es2020.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.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.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.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.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.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.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.generator.d.ts" => inc!("lib.es2015.generator.d.ts"),
|
||||||
"lib.es2015.iterable.d.ts" => inc!("lib.es2015.iterable.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.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.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" => {
|
"lib.es2015.symbol.wellknown.d.ts" => {
|
||||||
inc!("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.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.object.d.ts" => inc!("lib.es2017.object.d.ts"),
|
||||||
"lib.es2017.sharedmemory.d.ts" => inc!("lib.es2017.sharedmemory.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.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.es2017.typedarrays.d.ts" => inc!("lib.es2017.typedarrays.d.ts"),
|
||||||
"lib.es2018.asyncgenerator.d.ts" => inc!("lib.es2018.asyncgenerator.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.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.promise.d.ts" => inc!("lib.es2018.promise.d.ts"),
|
||||||
"lib.es2018.regexp.d.ts" => inc!("lib.es2018.regexp.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.array.d.ts" => inc!("lib.es2019.array.d.ts"),
|
||||||
"lib.es2019.object.d.ts" => inc!("lib.es2019.object.d.ts"),
|
"lib.es2019.object.d.ts" => inc!("lib.es2019.object.d.ts"),
|
||||||
"lib.es2019.string.d.ts" => inc!("lib.es2019.string.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.bigint.d.ts" => inc!("lib.esnext.bigint.d.ts"),
|
||||||
"lib.esnext.intl.d.ts" => inc!("lib.esnext.intl.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.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,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
100
std/manual.md
100
std/manual.md
|
@ -174,6 +174,12 @@ command line:
|
||||||
$ deno types
|
$ 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)
|
[This is what the output looks like.](https://github.com/denoland/deno/blob/master/cli/js/lib.deno_runtime.d.ts)
|
||||||
|
|
||||||
### Reference websites
|
### 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
|
the TypeScript compiler. Deno only looks for the directive in JavaScript (and
|
||||||
JSX) files.
|
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
|
### Testing if current file is the main program
|
||||||
|
|
||||||
To test if the current script has been executed as the main input to the program
|
To test if the current script has been executed as the main input to the program
|
||||||
|
|
Loading…
Reference in a new issue