Appearance
什么是模块
无论是ES6还是TypeScript,模块的导入导出都是十分常见的,这是为了代码能够不断地复用。模块在其自身的作用域里执行,而不是在全局作用域里所以模块化开发能够避免很多问题。定义在一个模块里的变量,函数,类等等在模块外部是不可见的,除非你明确地使用export形式之一导出它们。 相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,你必须要导入它们,可以使用import形式之一。
模块是自声明的;两个模块之间的关系是通过在文件级别上使用imports和exports建立的,TypeScript 支持多种模块化系统,包括 CommonJS、AMD(异步模块定义)、SystemJS、UMD 和 ES6 模块。
TypeScript 默认使用 ES6 模块语法。然而,TypeScript 提供了灵活的编译选项,允许开发者将 TypeScript 代码编译为 AMD 模块,以满足特定的项目需求。
导出
导出声明export
,任何声明(比如变量,函数,类,类型别名或接口)都能够通过添加export关键字来导出。
ts
export interface StringValidator {
isAcceptable(s: string): boolean;
}
export const numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return s.match(/^[A-Za-z]+$/);
}
}
导入
导入模块的语法是import module_name
。
导入一个模块中的某个特定导出:import { export_name } from 'module_name'
。
导入一个模块中的所有导出:import * as module_name from 'module_name'
。
ts
import { ZipCodeValidator } from './ZipCodeValidator';
// Some samples to try
let strings = ['Hello', '98052', '100'];
// Validators to use
let validators: { [s: string]: StringValidator; } = {
}
validators['ZIP code'] = new ZipCodeValidator();
validators['Letters only'] = new LettersOnlyValidator();
// Show whether each string passed each validator
for (let s of strings) {
for (let name in validators) {
console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches' : ' does not match') + ' ' + name);
}
}
默认导出
默认导出使用export default
,一个模块只能有一个默认导出。
ts
export default function add(x, y) {
return x + y;
}
导入默认导出
导入默认导出使用import
关键字,并且不需要使用大括号。
ts
import add from './mathUtils';
console.log(add(16, 26)); // 42
命名空间导出
命名空间导出使用export namespace
关键字,一个模块可以有多个命名空间导出。
ts
export namespace Geometry {
export function area(s: Shape) { ... }
export function circumference(s: Shape) { ... }
}
导入命名空间导出
导入命名空间导出使用import
关键字,并且需要使用大括号。
ts
import { area, circumference } from './Geometry';
模块解析策略
TypeScript 支持三种模块解析策略:
- Classic:Node.js 默认的解析策略。
- Node:与 Node.js 解析策略完全一致。
- ES6:实验性的解析策略。
模块解析策略设置
模块解析策略可以通过命令行选项或者通过配置文件设置。
ts
{
"compilerOptions": {
"moduleResolution": "node"
}
}
require
export = 和 import = require()。 CommonJS和AMD都有一个exports对象的概念,它包含了一个模块的所有导出内容。
它们也支持把exports替换为一个自定义对象。 默认导出就好比这样一个功能;然而,它们却并不相互兼容。 TypeScript模块支持export =语法以支持传统的CommonJS和AMD的工作流模型。
export =语法定义一个模块的导出对象。 它可以是类,接口,命名空间,函数或枚举。
若要导入一个使用了export =的模块时,必须使用TypeScript提供的特定语法import module = require("module")。
不过import只能声明在文件顶部,而require则可以在{}或者使用时按需引入require
是CommonJS规范的实现,import
是ES6规范的实现。
ts
const myModule = require('./myModule');
require 和 import 之间的主要区别在于它们的加载机制(同步与异步)、语法(动态与静态)和使用场景。随着 ES6 模块的普及,import 正在成为前端和后端 JavaScript 开发中的标准做法。然而,由于 Node.js 的长期支持,require 仍然在服务器端 JavaScript 中广泛使用。
js
import myModule from './myModule';
myModule.doSomething();