TypeScript 中的模块解析
模块解析的基本概念
模块解析是指 TypeScript 编译器在编译过程中确定导入语句(import)所引用模块实际路径的机制。TypeScript 支持两种模块解析策略:
- Classic:传统的模块解析策略(主要用于向后兼容)
- Node:模拟 Node.js 的模块解析机制(现代 TypeScript 项目的默认选择)
模块解析策略详解
Node 模块解析策略
当使用 --moduleResolution node(或 node16/nodenext)时,TypeScript 会按照以下顺序查找模块:
- 检查是否为 Node.js 内置模块(如
fs、path) - 检查当前目录的
node_modules- 查找
<moduleName>.ts/.tsx/.d.ts - 查找
package.json中的types或main字段
- 查找
- 向上级目录递归查找
node_modules - 检查全局类型声明(如
@types/<moduleName>)
Classic 模块解析策略
主要用于向后兼容,解析顺序更简单:
- 直接查找相对或绝对路径的
.ts文件 - 不自动搜索
node_modules
模块解析配置
在 tsconfig.json 中可以通过以下配置影响模块解析:
{
"compilerOptions": {
"moduleResolution": "node", // 或 "classic"
"baseUrl": "./", // 设置基础路径
"paths": { // 路径映射
"@components/*": ["src/components/*"]
}
}
}
路径映射(Path Mapping)
TypeScript 支持通过 paths 配置创建模块别名:
// 配置后可以这样导入
import { Button } from '@components/ui';
常见问题与解决方案
"Cannot find module" 错误
- 确保安装了依赖(
npm install) - 检查
@types/<package>是否存在 - 确认
tsconfig.json的include包含相关文件
- 确保安装了依赖(
不同文件扩展名的处理
- TypeScript 会依次尝试
.ts,.tsx,.d.ts,.js,.jsx
- TypeScript 会依次尝试
相对路径 vs 非相对路径
- 相对路径(
./file):基于当前文件解析 - 非相对路径(
lodash):基于node_modules或baseUrl解析
- 相对路径(
最佳实践
- 始终使用 Node 模块解析策略(默认)
- 对项目内部模块使用路径别名(
paths) - 为第三方库添加类型声明(
@types/或自定义.d.ts) - 保持
tsconfig.json和package.json的路径配置一致
示例:完整的模块解析流程
假设有以下结构:
project/
├── src/
│ ├── utils/
│ │ └── math.ts
│ └── app.ts
├── node_modules/
│ └── lodash/
└── tsconfig.json
当 app.ts 包含:
import { sum } from './utils/math';
import _ from 'lodash';
TypeScript 会:
- 将
./utils/math解析为src/utils/math.ts - 将
lodash解析为node_modules/lodash中的主文件
