简言
JavaScript 采用不同的方式处理代码模块化由来已久。从 2012 年开始,TypeScript 已经实现了对许多此类格式的支持,但随着时间的推移,社区和 JavaScript 规范已经趋同于一种名为 ES Modules(或 ES6 模块)的格式。
ES 模块于 2015 年被添加到 JavaScript 规范中,现在已经是官方支持的模块语法了。
模块
在 TypeScript 中,正如在 ECMAScript 2015 中一样,任何包含顶级导入或导出的文件都被视为模块。
相反,没有任何顶层导入或导出声明的文件会被视为脚本,其内容在全局范围内可用(因此也适用于模块)。JavaScript 规范声明,任何没有 import 声明、export 或顶级 await 的 JavaScript 文件都应被视为脚本而非模块。
模块在自己的作用域内执行,而不是在全局作用域内执行。这意味着在模块中声明的变量、函数、类等在模块外是不可见的,除非使用其中一种导出形式明确导出它们。相反,要使用从不同模块导出的变量、函数、类、接口等,则必须使用其中一种导入形式将其导入。
空模块
ts中可以更改为不导出任何内容的模块。无论模块目标是什么,该语法都有效。
语法:
export {};
表明这个文件是一个没有导出内容的模块。
ES Modules
ts中的ESM模块语法和js的高度相似。
基本
- 导入使用 import ,导出使用export
- 导出默认值
// @filename: hello.ts
export default function helloWorld() {
console.log("Hello, world!");
}
- 引入默认值
import helloWorld from "./hello.js";
helloWorld();
- 导出多个,导入多个
// @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;
}
import { pi, phi, absolute } from "./maths.js";
console.log(pi);
const absPhi = absolute(phi);
- 导入别名
import { pi as π } from "./maths.js";
- 可以使用 * 作为名称,将所有导出对象放入一个命名空间中
// @filename: app.ts
import * as math from "./maths.js";
console.log(math.pi);
const positivePhi = math.absolute(math.phi);
import type
类型使用export导出,可以使用import引入。
也可以专门使用 import type 引入类型。
import type { Cat, Dog } from "./animal.js";
export type Animals = Cat | Dog;
import type只能引入类型
TypeScript 4.5 还允许单个导入以 type 为前缀,以表示导入的引用是一个类型:
import { createCatName, type Cat, type Dog } from "./animal.js";
export type Animals = Cat | Dog;
const name = createCatName();
CommonJS
ts也支持CommonJS模块语法。
因为历史原因,CommonJS 是 npm 上大多数模块的交付格式。即使您使用上述 ES 模块语法进行编写,简要了解 CommonJS 语法的工作原理也有助于您更轻松地进行调试。
现在node也支持了ESM
不推荐ts项目使用CommonJS模块语法,类型可能需要.d.ts声明文件全局补充,麻烦。
导出
标识符可通过设置全局模块的 exports 属性导出。
function absolute(num: number) {
if (num < 0) return num * -1;
return num;
}
module.exports = {
pi: 3.14,
squareTwo: 1.41,
phi: 1.61,
absolute,
};
导入
const maths = require("./maths");
maths.pi;
// 或
const { squareTwo } = require("./maths");
squareTwo;
模块配置
在tsconfig.json(ts配置文件)中,target和module决定了项目的模块使用类型。
- module : 这决定了模块之间的交互使用哪些代码。(项目兼容范围)
- target : 决定哪些 JS 功能被降级(转换为在旧版 JavaScript 运行时中运行),哪些保持不变。(项目模块语法)
{
"compilerOptions": {
"target": "ES2015",
"module": "ES2015"
}
}
结语
结束了。