ES模块 #
一、模块概述 #
Deno使用标准的ES模块(ES Modules)作为模块系统,这是JavaScript的官方模块标准。与Node.js的CommonJS不同,ES模块使用 import 和 export 语法。
二、导出(export) #
2.1 命名导出 #
typescript
// utils.ts
// 导出变量
export const PI = 3.14159;
// 导出函数
export function add(a: number, b: number): number {
return a + b;
}
// 导出类
export class Calculator {
add(a: number, b: number): number {
return a + b;
}
}
// 导出接口
export interface User {
id: number;
name: string;
}
// 导出类型别名
export type ID = string | number;
2.2 导出语句 #
typescript
// math.ts
const PI = 3.14159;
function add(a: number, b: number): number {
return a + b;
}
function subtract(a: number, b: number): number {
return a - b;
}
// 统一导出
export { PI, add, subtract };
// 重命名导出
export { add as sum, subtract as diff };
2.3 默认导出 #
typescript
// calculator.ts
// 默认导出类
export default class Calculator {
add(a: number, b: number): number {
return a + b;
}
}
// 或默认导出函数
export default function greet(name: string): string {
return `Hello, ${name}!`;
}
// 或默认导出值
export default {
name: "default config",
version: "1.0.0"
};
2.4 重导出 #
typescript
// index.ts
// 重导出其他模块
export { add, subtract } from "./math.ts";
export { User } from "./types.ts";
// 重命名后导出
export { add as sum } from "./math.ts";
// 导出所有
export * from "./utils.ts";
// 导出为命名空间
export * as Utils from "./utils.ts";
三、导入(import) #
3.1 命名导入 #
typescript
// main.ts
import { add, subtract, PI } from "./math.ts";
console.log(add(1, 2)); // 3
console.log(subtract(5, 3)); // 2
console.log(PI); // 3.14159
3.2 重命名导入 #
typescript
import { add as sum, subtract as diff } from "./math.ts";
console.log(sum(1, 2)); // 3
console.log(diff(5, 3)); // 2
3.3 导入默认导出 #
typescript
import Calculator from "./calculator.ts";
const calc = new Calculator();
console.log(calc.add(1, 2)); // 3
3.4 混合导入 #
typescript
import Calculator, { add, subtract } from "./calculator.ts";
const calc = new Calculator();
console.log(add(1, 2));
3.5 导入所有 #
typescript
import * as Math from "./math.ts";
console.log(Math.add(1, 2)); // 3
console.log(Math.subtract(5, 3)); // 2
console.log(Math.PI); // 3.14159
3.6 仅执行模块 #
typescript
// 执行模块但不导入任何内容
import "./setup.ts";
3.7 动态导入 #
typescript
async function loadModule() {
const module = await import("./math.ts");
console.log(module.add(1, 2)); // 3
}
loadModule();
四、模块解析 #
4.1 相对路径 #
typescript
import { add } from "./math.ts"; // 当前目录
import { User } from "../types/user.ts"; // 上级目录
import { config } from "./config/app.ts"; // 子目录
4.2 绝对路径 #
typescript
import { config } from "/Users/user/project/config.ts";
4.3 URL导入 #
typescript
// 从远程URL导入
import { serve } from "https://deno.land/std@0.208.0/http/server.ts";
// 从GitHub导入
import { someModule } from "https://raw.githubusercontent.com/user/repo/main/mod.ts";
// 从CDN导入
import lodash from "https://cdn.skypack.dev/lodash";
4.4 npm包导入 #
typescript
// 使用npm:前缀
import express from "npm:express@4";
import { z } from "npm:zod";
const app = express();
4.5 jsr包导入 #
typescript
// 使用jsr:前缀
import { encodeBase64 } from "jsr:@std/encoding/base64";
const encoded = encodeBase64(new TextEncoder().encode("hello"));
console.log(encoded);
五、模块结构 #
5.1 项目结构 #
text
project/
├── deno.json
├── main.ts
├── src/
│ ├── index.ts
│ ├── utils/
│ │ ├── mod.ts
│ │ ├── math.ts
│ │ └── string.ts
│ └── types/
│ ├── mod.ts
│ └── user.ts
└── tests/
└── main_test.ts
5.2 模块入口 #
typescript
// src/utils/mod.ts
export { add, subtract } from "./math.ts";
export { capitalize, reverse } from "./string.ts";
// 使用时
import { add, capitalize } from "./src/utils/mod.ts";
5.3 deno.json配置 #
json
{
"name": "@my-org/my-project",
"version": "1.0.0",
"exports": "./src/mod.ts",
"imports": {
"@std/http": "jsr:@std/http@^1.0.0",
"@/utils": "./src/utils/mod.ts"
}
}
六、循环依赖 #
6.1 循环依赖问题 #
typescript
// a.ts
import { b } from "./b.ts";
export const a = 1;
console.log(b);
// b.ts
import { a } from "./a.ts";
export const b = a + 1; // a可能是undefined
6.2 解决方案 #
typescript
// 方案1:重构代码,消除循环依赖
// 方案2:延迟导入
// a.ts
export const a = 1;
export function getB() {
const { b } = await import("./b.ts");
return b;
}
// 方案3:使用函数延迟访问
// b.ts
import { a } from "./a.ts";
export const b = () => a + 1;
七、模块缓存 #
7.1 缓存位置 #
bash
# 查看缓存位置
deno info --location
# macOS/Linux: ~/.cache/deno
# Windows: %LOCALAPPDATA%\deno
7.2 缓存命令 #
bash
# 缓存依赖
deno cache main.ts
# 重新加载所有依赖
deno cache --reload main.ts
# 重新加载特定依赖
deno cache --reload=https://deno.land/std main.ts
7.3 锁定文件 #
bash
# 生成锁定文件
deno cache --lock=deno.lock --lock-write main.ts
# 使用锁定文件
deno cache --lock=deno.lock main.ts
八、最佳实践 #
8.1 使用mod.ts作为入口 #
typescript
// src/mod.ts
export { add, subtract } from "./math.ts";
export { User, Product } from "./types.ts";
8.2 使用类型导出 #
typescript
// types.ts
export type { User, Product };
// 使用时
import type { User } from "./types.ts";
8.3 避免副作用 #
typescript
// 不推荐:模块有副作用
// config.ts
export const config = {};
localStorage.setItem("key", "value"); // 副作用
// 推荐:纯模块
// config.ts
export const config = {};
export function initialize() {
localStorage.setItem("key", "value");
}
九、总结 #
本章学习了:
- ES模块的基本概念
- export导出语法
- import导入语法
- 模块解析规则
- 模块结构组织
- 循环依赖处理
- 模块缓存管理
- 最佳实践
下一章,我们将学习导入导出详解。
最后更新:2026-03-28