使用esbuild时共享包无法导入子路径模块的解决问询
1. 修正package.json的exports字段配置
exports是Node.js识别子路径导入的核心,必须严格映射构建后的文件结构。示例配置如下:
{ "name": "@shared", "type": "module", "exports": { ".": "./dist/index.js", "./utils": { "import": "./dist/utils/index.js", "types": "./dist/utils/index.d.ts" }, "./hooks": { "import": "./dist/hooks/index.js", "types": "./dist/hooks/index.d.ts" } }, // 主类型入口 "types": "./dist/index.d.ts", // 兼容旧版TypeScript的子路径类型映射 "typesVersions": { "*": { "utils": ["./dist/utils/index.d.ts"], "hooks": ["./dist/hooks/index.d.ts"] } } }
- 每个子路径键(如
./utils)必须对应到构建后实际存在的文件路径。 - 条件导出(
import/types)确保ES模块和TypeScript都能正确解析。
2. 调整TypeScript配置
确保tsconfig.json的模块解析和类型生成配置正确:
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "bundler", // 或node16/nodenext,适配Node.js模块解析逻辑 "target": "ES2020", "declaration": true, // 生成类型声明文件 "declarationDir": "./dist", // 类型文件输出到dist目录 "outDir": "./dist", // 编译后的JS文件输出到dist目录 "strict": true, "esModuleInterop": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
moduleResolution设为bundler时,兼容esbuild、webpack等打包工具的解析逻辑;设为node16则严格遵循Node.js的ES模块规则。- 必须开启
declaration并指定declarationDir,确保子路径的类型文件被正确生成到对应位置。
3. 配置esbuild构建输出
esbuild需要单独打包每个子路径入口,而非合并成单个文件。示例构建脚本:
const esbuild = require('esbuild'); async function buildSharedPackage() { await esbuild.build({ entryPoints: [ 'src/index.ts', 'src/utils/index.ts', 'src/hooks/index.ts' ], outdir: 'dist', bundle: false, // 库模式下禁用bundle,保留独立模块 format: 'esm', // 输出ES模块,对应package.json的type: module platform: 'node', sourcemap: true, tsconfig: './tsconfig.json' }); } buildSharedPackage().catch(err => { console.error(err); process.exit(1); });
bundle: false是关键,否则esbuild会将所有代码打包到一个文件,导致子路径无法独立解析。- 若需兼容CommonJS,可添加额外构建步骤生成
.cjs格式文件,并在exports中对应映射。
4. 验证与排查
- 检查dist目录结构:确保
dist/utils/index.js、dist/hooks/index.js及对应的.d.ts文件存在。 - 本地调试时,使用
npm link将共享包链接到依赖项目,避免缓存问题。 - 依赖项目的tsconfig.json中,
moduleResolution需与共享包保持一致(如bundler或node16)。 - 若使用pnpm/yarn,删除
node_modules和锁文件后重新安装,清除缓存。
内容的提问来源于stack exchange,提问作者user22915075
相关产品推荐
相关产品推荐

