You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:30:46