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