這是一個(gè)不穩(wěn)定的 Deno 特性。 更多信息請(qǐng)查閱 穩(wěn)定性 Deno 支持對(duì)內(nèi)置 TypeScript 編譯器的運(yùn)行時(shí)訪問。Deno 命名空間中有三種方法提供此訪問。
這類似于 deno cache,因?yàn)樗梢垣@取代碼、緩存代碼、編譯代碼,但不運(yùn)行代碼。它最多接受三個(gè)參數(shù),rootName、可選的 sources 和可選的 options。 rootName 是用于生成目標(biāo)程序的根模塊。這類似于在 deno run --reload example.ts 中在命令行上傳遞的模塊名。 sources 是一個(gè)哈希表,其中鍵是完全限定的模塊名稱,值是模塊的文本源。如果傳遞了 sources,Deno 將從該哈希表中解析所有模塊,而不會(huì)嘗試在 Deno 之外解析它們。如果沒有提供 sources,Deno 將解析模塊,就像根模塊已經(jīng)在命令行上傳遞了一樣。Deno 還將緩存所有的這些資源。所有已解析的資源都會(huì)被當(dāng)成動(dòng)態(tài)導(dǎo)入對(duì)待,導(dǎo)入行為是否需要讀取和網(wǎng)絡(luò)權(quán)限取決于目標(biāo)在本地還是遠(yuǎn)程。 options 參數(shù)是一組 Deno.CompilerOptions 類型的選項(xiàng),它是包含 Deno 支持選項(xiàng)的 TypeScript 編譯器選項(xiàng)的子集。 該方法返回元組。第一個(gè)參數(shù)包含與代碼相關(guān)的任何診斷信息(語法或類型錯(cuò)誤)。第二個(gè)參數(shù)是一個(gè)映射,其中鍵是輸出文件名,值是內(nèi)容。 提供 sources 的一個(gè)例子:
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); // 確保沒有返回診斷信息
console.log(emitMap);
我們希望 map 包含 4 個(gè) “文件(files)” ,分別命名為 /foo.js.map
,/foo.js
,/bar.js.map
,和 /bar.js
。
當(dāng)不提供資源時(shí),您可以使用本地或遠(yuǎn)程模塊,就像在命令行上做的那樣。所以您可以這樣做:
const [diagnostics, emitMap] = await Deno.compile(
"https://deno.land/std/examples/welcome.ts"
);
在這種情況下,emitMap 將包含一個(gè) console.log() 語句。
這與 deno bundle
在命令行上的工作非常相似。 它也與 Deno.compile() 類似,只是它不返回文件映射,而是只返回一個(gè)字符串,這是一個(gè)自包含的 JavaScript ES 模塊,它將包含提供或解析的所有代碼,以及提供的根模塊的所有導(dǎo)出。它最多接受三個(gè)參數(shù),rootName、可選的 sources 和可選的 options。
rootName 是用于生成目標(biāo)程序的根模塊。這類似于在 deno bundle example.ts 中在命令行上傳遞的模塊名。
sources 是一個(gè)哈希表,其中鍵是完全限定的模塊名稱,值是模塊的文本源。如果傳遞了 sources,Deno 將從該哈希表中解析所有模塊,而不會(huì)嘗試在 Deno 之外解析它們。如果沒有提供 sources,Deno 將解析模塊,就像根模塊已經(jīng)在命令行上傳遞了一樣。Deno 還將緩存所有的這些資源。所有已解析的資源都會(huì)被當(dāng)成動(dòng)態(tài)導(dǎo)入對(duì)待,導(dǎo)入行為是否需要讀取和網(wǎng)絡(luò)權(quán)限取決于目標(biāo)在本地還是遠(yuǎn)程。
options 參數(shù)是一組 Deno.CompilerOptions 類型的選項(xiàng),它是包含 Deno 支持選項(xiàng)的 TypeScript 編譯器選項(xiàng)的子集。
提供 sources 的一個(gè)例子:
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); // 確保沒有返回診斷信息
console.log(emit);
我們希望 emit 是一個(gè) ES 模塊的文本,它將包含兩個(gè)模塊的輸出源。 當(dāng)不提供資源時(shí),您可以使用本地或遠(yuǎn)程模塊,就像在命令行上做的那樣。所以您可以這樣做:
const [diagnostics, emit] = await Deno.bundle(
"https://deno.land/std/http/server.ts"
);
在這種情況下,emit 將是一個(gè)自包含的 JavaScript ES 模塊,并解析了所有依賴項(xiàng),導(dǎo)出與源模塊相同的導(dǎo)出。 Deno.transpileOnly() 這是基于 TypeScript 函數(shù) transpileModule() 的。所有這些操作都會(huì)“擦除”模塊中的任何類型并釋放 JavaScript。沒有類型檢查和依賴關(guān)系的解析。它最多接受兩個(gè)參數(shù),第一個(gè)參數(shù)是哈希表,其中鍵是模塊名稱,值是內(nèi)容。模塊名稱的唯一用途是在將信息放入源映射時(shí),顯示源文件名稱是什么。第二個(gè)參數(shù)包含 Deno.CompilerOptions 類型的可選 options。函數(shù)通過映射解析,其中鍵是提供的源模塊名稱,值是具有 source 屬性和可選 map 屬性的對(duì)象。第一個(gè)是模塊的輸出內(nèi)容。 map 屬性是源映射。源映射是默認(rèn)提供的,但可以通過 options 參數(shù)關(guān)閉。 舉個(gè)例子:
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 被重寫成一個(gè)構(gòu)造可枚舉的 IIFE,并且映射被定義。 引用 TypeScript 庫文件 當(dāng)您使用 deno run 或其他 TypeScript 類型的 Deno 命令時(shí),該代碼將根據(jù)描述 Deno 支持的環(huán)境的自定義庫進(jìn)行評(píng)估。默認(rèn)情況下,TypeScript 類型的編譯器運(yùn)行時(shí) API 也使用這些庫(Deno.compile() 和 Deno.bundle())。 但是,如果您希望為其他運(yùn)行時(shí)編譯或捆綁 TypeScript,則您可能希望重載默認(rèn)庫。為此,運(yùn)行時(shí) API 支持編譯器選項(xiàng)中的 lib 屬性。例如,如果你的 TypeScript 代碼是為瀏覽器準(zhǔn)備的,您可以使用 TypeScript 的 "dom" 庫:
const [errors, emitted] = await Deno.compile(
"main.ts",
{
"main.ts": `document.getElementById("foo");\n`,
},
{
lib: ["dom", "esnext"],
}
);
有關(guān) TypeScript 支持的所有庫的列表,請(qǐng)參見 lib 編譯器選項(xiàng)。 不要忘記包含 JavaScript 庫 就像 tsc 一樣,當(dāng)您提供一個(gè) lib 編譯器選項(xiàng)時(shí),它會(huì)覆蓋默認(rèn)的選項(xiàng),這意味著基本的 JavaScript 庫不會(huì)被包含,而您應(yīng)該包含最能代表您的目標(biāo)運(yùn)行時(shí)的選項(xiàng)(例如 es5,es2015,es2016,es2017,es2018,es2019,es2020 或 esnext)。
除了 TypeScript 提供的庫之外,還有四個(gè)內(nèi)置在 Deno 中的庫可以引用:
const [errors, emitted] = await Deno.compile(
"main.ts",
{
"main.ts": `document.getElementById("foo");\n`,
},
{
lib: ["dom", "esnext", "deno.ns"],
}
);
注意,Deno 命名空間需要一個(gè) ES2018 或更新的運(yùn)行時(shí)環(huán)境。這意味著,如果您使用的庫“低于” ES2018,那么您將得到編譯過程中輸出的錯(cuò)誤。
您不必在編譯器選項(xiàng)中指定 lib。Deno 支持對(duì)庫的三斜杠引用,并可以嵌入到文件的內(nèi)容中。舉個(gè)例子,如果你有一個(gè) main.ts: /// <reference lib="dom" />
document.getElementById("foo"); 它可以編譯,且不會(huì)出現(xiàn)下面這樣的錯(cuò)誤: const [errors, emitted] = await Deno.compile("./main.ts", undefined, { lib: ["esnext"], }); 注意,dom 庫與 Deno 的默認(rèn)類型庫中定義的一些默認(rèn)全局變量有沖突。為了避免這種情況,需要在編譯器選項(xiàng)中為運(yùn)行時(shí)編譯器 API 指定一個(gè) lib 選項(xiàng)。
更多建議: