Rollup+TypeScript子路径导入生成多余目录问题排查
问题
我参考多篇文章实现了Rollup+TypeScript的子路径导入,目标是像Material-UI那样支持import Button1 from @lib/Button的单组件导入,但构建后dist/esm/Button目录下多出了一个同名子目录,里面全是类型声明文件,结构如下:
当前代码结构
src/index.ts import * from "./Button" src/Button/index.ts export { default as Button1 } from "./Button1" ... 其他导出 ... src/Button/Button1.ts export default Button1
构建后异常目录结构
dist/esm/Button: Button CustomButton.d.ts index.js package.json Button.d.ts index.d.ts index.js.map dist/esm/Button/Button: Button.d.ts CustomButton.d.ts index.d.ts
怀疑问题出在tsconfig或rollup配置中,附配置文件:
tsconfig.json
{ "compilerOptions": { "target": "es5", "module": "ESNext", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "noImplicitAny": true, "jsx": "react", "noImplicitReturns": true, "exactOptionalPropertyTypes": true, "noUnusedLocals": true, "noUnusedParameters": true, "rootDir": "src", "declaration": true, "declarationDir": "dist", "sourceMap": true, "moduleResolution": "node", "allowSyntheticDefaultImports": true, "emitDeclarationOnly": true }, "include": ["src/**/*"], "exclude": [ "node_modules", "build" ] }
rollup.config.js
export default [ { input: "src/index.ts", output: [ { file: packageJson.main, sourcemap: true, format: "cjs", }, { file: packageJson.module, sourcemap: true, format: "esm", }, ], plugins: plugins }, { input: "dist/esm/index.d.ts", output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts()], external: [/\.css$/, /\.scss$/, /\.sass$/] }, ...folderBuilds ] const subfolderPlugins = (folderName) => [ ...plugins, generatePackageJson({ baseContents: { name: `${packageJson.name}/${folderName}`, private: true, main: "../cjs/index.js", module: "../esm/index.js", types: "./index.d.ts" } }) ] const folderBuilds = getFolders("./src").map(folder => ( { input: `src/${folder}/index.ts`, output: { file: `dist/esm/${folder}/index.js`, sourcemap: true, format: 'esm', }, plugins: subfolderPlugins(folder), } ));
解决方案
1. 修复tsconfig.json配置
问题核心是TypeScript自行生成类型文件的逻辑与Rollup的dts插件冲突,导致类型目录重复嵌套:
{ "compilerOptions": { "target": "es5", "module": "ESNext", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "noImplicitAny": true, "jsx": "react", "noImplicitReturns": true, "exactOptionalPropertyTypes": true, "noUnusedLocals": true, "noUnusedParameters": true, "rootDir": "src", "sourceMap": true, "moduleResolution": "node", "allowSyntheticDefaultImports": true, // 关闭TypeScript单独生成类型的功能,交给Rollup的dts插件处理 "emitDeclarationOnly": false, "declaration": false }, "include": ["src/**/*"], "exclude": [ "node_modules", "dist" // 新增排除dist目录,避免重复处理旧文件 ] }
2. 修复rollup.config.js配置
需要给每个子目录单独添加类型构建任务,同时修正根类型的生成路径:
// 新增子目录类型构建任务 const subfolderDtsBuilds = getFolders("./src").map(folder => ( { input: `src/${folder}/index.ts`, output: [{ file: `dist/esm/${folder}/index.d.ts`, format: "esm" }], plugins: [dts()], external: [/\.css$/, /\.scss$/, /\.sass$/] } )); export default [ { input: "src/index.ts", output: [ { file: packageJson.main, sourcemap: true, format: "cjs", }, { file: packageJson.module, sourcemap: true, format: "esm", }, ], plugins: plugins // 确保plugins包含@rollup/plugin-typescript处理TS编译 }, { input: "src/index.ts", // 直接从源码生成根类型,而非从dist读取 output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts()], external: [/\.css$/, /\.scss$/, /\.sass$/] }, ...folderBuilds, ...subfolderDtsBuilds // 加入子目录类型构建任务 ]
额外注意事项
- 确保
getFolders函数仅返回src下的子目录(排除index.ts等文件) - 构建前清理dist目录,避免残留旧文件
- 确认Rollup的plugins数组包含
@rollup/plugin-typescript,并配置使用当前tsconfig
内容的提问来源于stack exchange,提问作者Tucan
相关产品推荐
相关产品推荐

