TypeScript 里的 module 概念
Modules
JavaScript 在處理模塊化代碼方面有著悠久的歷史。 TypeScript 自 2012 年問世以來,已經(jīng)實現(xiàn)了對許多這些格式的支持,但隨著時間的推移,社區(qū)和 JavaScript 規(guī)范已經(jīng)融合到一種稱為 ES 模塊(或 ES6 模塊)的格式上。 您可能知道它是 import/export 語法。
ES Modules 于 2015 年添加到 JavaScript 規(guī)范中,到 2020 年在大多數(shù) Web 瀏覽器和 JavaScript 運行時中得到廣泛支持。
為了重點,手冊將涵蓋 ES 模塊及其流行的前體 CommonJS module.exports = 語法,您可以在模塊下的參考部分中找到有關(guān)其他模塊模式的信息。
How JavaScript Modules are Defined
在 TypeScript 中,就像在 ECMAScript 2015 中一樣,任何包含頂級導(dǎo)入或?qū)С龅奈募急灰暈橐粋€模塊。
相反,沒有任何頂級導(dǎo)入或?qū)С雎暶鞯奈募灰暈槟_本,其內(nèi)容在全局范圍內(nèi)可用(因此也對模塊可用)。
模塊在它們自己的范圍內(nèi)執(zhí)行,而不是在全局范圍內(nèi)。 這意味著在模塊中聲明的變量、函數(shù)、類等在模塊外部不可見,除非它們使用導(dǎo)出形式之一顯式導(dǎo)出。 相反,要使用從不同模塊導(dǎo)出的變量、函數(shù)、類、接口等,必須使用其中一種導(dǎo)入形式導(dǎo)入。
非模塊
在我們開始之前,了解 TypeScript 將什么視為模塊很重要。 JavaScript 規(guī)范聲明任何沒有導(dǎo)出或頂級 await 的 JavaScript 文件都應(yīng)被視為腳本而不是模塊。
在腳本文件中,變量和類型被聲明為在共享全局范圍內(nèi),并且假設(shè)您將使用 --outFile 編譯器選項將多個輸入文件連接到一個輸出文件中,或者在其中使用多個
<script> 標記 您的 HTML 以加載這些文件(以正確的順序!)。
如果您有一個當前沒有任何導(dǎo)入或?qū)С龅奈募?#xff0c;但您希望被視為一個模塊,請?zhí)砑右韵滦?#xff1a;
export {};這會將文件更改為不導(dǎo)出任何內(nèi)容的模塊。 無論您的模塊目標如何,此語法都有效。
ES Module 語法
文件可以通過 export default 聲明主導(dǎo)出:
// @filename: hello.ts export default function helloWorld() {console.log("Hello, world!"); }This is then imported via:
import hello from "./hello.js"; hello();除了默認導(dǎo)出之外,您還可以通過省略默認導(dǎo)出來導(dǎo)出多個變量和函數(shù):
// @filename: maths.ts export var pi = 3.14; export let squareTwo = 1.41; export const phi = 1.61;export class RandomNumberGenerator {}export function absolute(num: number) {if (num < 0) return num * -1;return num; }在另一個文件里用大括號導(dǎo)入:
import { pi, phi, absolute } from "./maths.js";console.log(pi); const absPhi = absolute(phi);還可以用 import alias 語法:
import { pi as π } from "./maths.js";console.log(π);您可以將所有導(dǎo)出的對象放入一個使用 * 作為名稱的命名空間中:
// @filename: app.ts import * as math from "./maths.js";console.log(math.pi); const positivePhi = math.absolute(math.phi);直接 import 一個文件會有什么后果?
// @filename: app.ts import "./maths.js";console.log("3.14");在這種情況下,導(dǎo)入什么都不做。 但是,對 maths.ts 中的所有代碼都進行了評估,這可能會觸發(fā)影響其他對象的副作用。
TypeScript 增強了 import 語法,可以只 import module 里的 type 定義。
// @filename: animal.ts export type Cat = { breed: string; yearOfBirth: number }; 'createCatName' cannot be used as a value because it was imported using 'import type'. export type Dog = { breeds: string[]; yearOfBirth: number }; export const createCatName = () => "fluffy";// @filename: valid.ts import type { Cat, Dog } from "./animal.js"; export type Animals = Cat | Dog;// @filename: app.ts import type { createCatName } from "./animal.js"; const name = createCatName();TypeScript’s Module Resolution Options
模塊解析是從 import 或 require 語句中獲取字符串并確定該字符串引用哪個文件的過程。
TypeScript 包括兩種解析策略:Classic 和 Node。 經(jīng)典,當編譯器標志模塊不是 commonjs 時的默認值,包含在內(nèi)是為了向后兼容。 Node 策略復(fù)制了 Node.js 在 CommonJS 模式下的工作方式,并額外檢查了 .ts 和 .d.ts。
有許多 TSConfig 標志會影響 TypeScript 中的模塊策略:moduleResolution、baseUrl、paths、rootDirs。
有關(guān)這些策略如何工作的完整詳細信息,您可以查閱模塊解決方案。
TypeScript’s Module Output Options
有兩個選項會影響發(fā)出的 JavaScript 輸出:
- target 確定哪些 JS 功能被降級(轉(zhuǎn)換為在較舊的 JavaScript 運行時中運行)以及哪些保持不變
- module:確定模塊之間使用哪些代碼進行交互的模塊
您使用的目標取決于您希望在其中運行 TypeScript 代碼的 JavaScript 運行時中可用的功能。這可能是:您支持的最舊的 Web 瀏覽器,您希望運行或可能來自的最低版本的 Node.js 來自您的運行時的獨特約束——例如 Electron。
模塊之間的所有通信都通過模塊加載器進行,編譯器標志模塊確定使用哪一個。在運行時,模塊加載器負責在執(zhí)行之前定位并執(zhí)行模塊的所有依賴項。
例如,這是一個使用 ES 模塊語法的 TypeScript 文件,展示了模塊的幾個不同選項。
下面是 TypeScript 原始文件:
import { valueOfPi } from "./constants.js";export const twoPi = valueOfPi * 2;下面是 ES2020 output:
import { valueOfPi } from "./constants.js"; export const twoPi = valueOfPi * 2;下面是 CommonJS:
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.twoPi = void 0; const constants_js_1 = require("./constants.js"); exports.twoPi = constants_js_1.valueOfPi * 2;下面是 UMD:
(function (factory) {if (typeof module === "object" && typeof module.exports === "object") {var v = factory(require, exports);if (v !== undefined) module.exports = v;}else if (typeof define === "function" && define.amd) {define(["require", "exports", "./constants.js"], factory);} })(function (require, exports) {"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.twoPi = void 0;const constants_js_1 = require("./constants.js");exports.twoPi = constants_js_1.valueOfPi * 2; });總結(jié)
以上是生活随笔為你收集整理的TypeScript 里的 module 概念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel宏教程 (宏的介绍与基本使用)
- 下一篇: 实用分享-在线公式编辑器(可导图识别)[