模块导出问题
DDD架构中domain-client模块导入问题解决
[!info] related notes
Domain-Client 模块导入问题解决指南
问题背景
在DDD架构重构过程中,我们创建了@dailyuse/domain-client包作为前端应用的领域对象统一入口。然而,在集成过程中遇到了持续的模块导入错误:
Cannot find module '@dailyuse/domain-client' or its corresponding type declarations.ts(2307)
问题分析
1. 根本原因
问题核心:TypeScript无法找到正确的模块声明文件和JavaScript输出文件
具体表现为:
import { User } from '@dailyuse/domain-client'报错- VS Code无法解析模块路径
- 编译时找不到类型定义
2. 技术层面原因
2.1 Package.json配置错误
// 错误的配置
{
"main": "src/index.ts", // 指向源码而非编译后文件
"types": "src/index.ts", // 类型定义应该指向.d.ts文件
"exports": {
".": "src/index.ts" // 导出路径错误
}
}
2.2 构建工具问题
最初使用的tsup构建工具在Windows环境下存在以下问题:
- Rollup依赖的路径解析在Windows下有兼容性问题
- 生成的文件扩展名不匹配(.d.mts vs .d.ts)
- 复杂的配置导致输出文件结构混乱
2.3 TypeScript路径映射缺失
Web应用的tsconfig.json缺少正确的路径映射配置:
{
"compilerOptions": {
"paths": {
"@dailyuse/*": ["../../packages/*/src"]
}
}
}
解决方案
步骤1: 替换构建工具
从tsup切换到原生TypeScript编译器
# 删除tsup相关配置
npm uninstall tsup
# 创建专用的构建配置
# packages/domain-client/tsconfig.build.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"removeComments": false
},
"include": ["src/**/*"],
"exclude": ["src/**/*.test.ts", "src/**/*.spec.ts", "dist", "node_modules"]
}
步骤2: 修正Package.json配置
{
"name": "@dailyuse/domain-client",
"version": "1.0.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"scripts": {
"build": "npx tsc --project tsconfig.build.json",
"dev": "npx tsc --project tsconfig.build.json --watch"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
}
}
步骤3: 执行构建
cd packages/domain-client
npx tsc --project tsconfig.build.json
构建结果:
packages/domain-client/
├── dist/
│ ├── index.js
│ ├── index.d.ts
│ ├── index.d.ts.map
│ └── index.js.map
├── src/
└── package.json
步骤4: 刷新工作区链接
# 根目录执行
pnpm install
步骤5: 验证解决方案
创建测试文件验证导入:
// apps/web/src/test-import.ts
import { User } from '@dailyuse/domain-client';
console.log('Import successful:', User);
技术原理解析
1. Node.js模块解析机制
Node.js按以下顺序解析模块:
- 查找
node_modules/@dailyuse/domain-client/package.json - 读取
main字段指向的入口文件 - 查找对应的类型声明文件(
types字段)
2. TypeScript类型解析
TypeScript编译器需要:
- JavaScript运行时文件(.js)
- 类型声明文件(.d.ts)
- 正确的package.json配置
3. PNPM工作区链接
PNPM通过符号链接(symlink)将本地包链接到node_modules:
node_modules/@dailyuse/domain-client -> ../../packages/domain-client
预防措施
1. 标准化构建流程
为所有domain包创建统一的构建配置:
// 标准tsconfig.build.json模板
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"declaration": true,
"declarationMap": true
},
"include": ["src/**/*"],
"exclude": ["**/*.test.ts", "**/*.spec.ts", "dist"]
}
2. Package.json检查清单
每个包发布前检查:
-
main指向编译后的.js文件 -
types指向编译后的.d.ts文件 -
files数组包含dist目录 -
exports配置正确
3. 自动化验证脚本
创建验证脚本检查包的完整性:
#!/bin/bash
# scripts/verify-package.sh
PACKAGE_PATH=$1
cd $PACKAGE_PATH
# 检查构建输出
if [ ! -f "dist/index.js" ]; then
echo "❌ Missing dist/index.js"
exit 1
fi
if [ ! -f "dist/index.d.ts" ]; then
echo "❌ Missing dist/index.d.ts"
exit 1
fi
echo "✅ Package structure valid"
常见错误诊断
错误1: Cannot find module
原因: package.json配置错误或构建输出缺失 解决: 检查main/types字段,重新构建
错误2: Type definitions not found
原因: .d.ts文件缺失或路径错误 解决: 确保types字段指向正确的.d.ts文件
错误3: Module resolution failed
原因: TypeScript路径映射配置错误 解决: 检查tsconfig.json的paths配置
最佳实践
- 统一构建工具: 使用TypeScript原生编译器而非第三方工具
- 标准化配置: 所有domain包使用相同的构建配置
- 版本控制: 将dist目录加入.gitignore,发布时构建
- 持续验证: 在CI/CD中添加包完整性检查
总结
Domain-client导入问题的解决关键在于:
- 正确的package.json配置
- 可靠的构建工具选择
- 完整的TypeScript类型声明
- 正确的工作区链接
通过系统性地解决这些问题,我们建立了稳定可靠的domain包导入机制。
其他问题
- package 的 main 不是指向入口文件的吗,怎么这里是指向编译结果文件了;还是说它是告诉使用这个包的人,入口文件在哪里?
main字段确实是告诉Node.js该包的入口文件位置
运行时入口:main字段指向的是运行时实际加载的JavaScript文件(编译后的输出文件),而不是源代码文件
开发与生产分离:
- 开发时:我们编写的是src/index.ts
- 构建后:生成dist/index.js
- 使用时:Node.js/浏览器加载的是dist/index.js
正确配置示例:
{
"main": "dist/index.js", // 运行时入口
"types": "dist/index.d.ts", // 类型声明入口
"files": ["dist"] // 发布包含的文件
}
为什么不能指向源码: TypeScript文件不能直接执行 需要经过编译转换为JavaScript 类型声明需要单独生成(.d.ts)
- 之前错误的原因是默认导出的文件位置和 package 指定的位置不同,所以找不到吗;默认导出的位置是哪里