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

自研React组件库使用报错:无法解析文件路径

React组件库作为依赖引入的问题排查与解决

背景

自研React组件库(下称LIB),配置了"type": "module",仅通过tsc命令编译生成dist目录,希望在其他项目中作为依赖引入使用。

LIB文件结构

.
└── LIB/
    └── src/
        └── container/
            ├── index.ts
            ├── container.tsx
            ├── container-footer.tsx
            └── ...

container/index.ts 代码

export * from './container';
export * from './container-footer';
export ...

疑问:ContainerFooter组件仅在Container内部导入使用,不会对外单独调用,是否不该在index.ts中导出?

container/container.tsx 代码

import { ContainerFooter } from './container-footer';

const Container = props => (
    <div>
        {/* Some stuff here */}

        {props.showFooter && <ContainerFooter />}
    </div>
)

遇到的问题

问题1:无法顶层导入组件

尝试通过import { Container } from '@company_name/LIB'导入时,报错:

ERROR in ./src/App.tsx
export ‘Container’ (imported as ‘Container’) was not found in ‘@company_name/LIB’ (module has no exports)

问题2:从dist目录导入时模块解析失败

尝试import { Container } from '@company_name/LIB/dist/container/container'(或@company_name/LIB/dist/container)时,报错:

ERROR in ./node_modules/@company_name/LIB/dist/container/container.js 6:0-47
Module not found: Error: Can't resolve './container-footer' in '/Users/username/git/NEW_PROJECT/node_modules/@company_name/LIB/dist/container'
Did you mean 'container-footer.js'?
BREAKING CHANGE: The request './container-footer' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains "type": "module").
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

LIB相关配置

package.json(非依赖部分)

{
    "files": [
        "dist"
    ],
    "main": "dist/index.js",
    "type": "module",
    "types": "dist/index.d.ts",
    "scripts": {
        "build": "tsc",
        ...
    }
    ...
}

tsconfig.json

{
    "compilerOptions": {
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "baseUrl": "src",
        "declaration": true,
        "emitDecoratorMetadata": true,
        "esModuleInterop": true,
        "experimentalDecorators": true,
        "isolatedModules": true,
        "jsx": "react-jsx",
        "lib": [
            "dom",
            "dom.iterable",
            "esnext"
        ],
        "module": "esnext",
        "moduleResolution": "node",
        "outDir": "dist",
        "resolveJsonModule": true,
        "rootDirs": [
            "src"
        ],
        "skipLibCheck": true,
        "sourceMap": true,
        "strict": true,
        "strictNullChecks": false,
        "target": "esnext"
    },
    "include": [
        "src/**/*"
    ]
}

解决方案

解决问题2:模块解析缺少扩展名

  • 原因:LIB配置了"type": "module",属于严格ES模块,Node.js的ES模块规范要求导入路径必须带完整文件扩展名。但当前tsconfig.json中moduleResolution设为node,TypeScript不会自动给编译后的JS文件添加扩展名,导致导入路径找不到对应文件。
  • 修复方法:
    1. 将tsconfig.json中compilerOptions.moduleResolution改为nodenext(TypeScript 4.7+支持)或bundler(TypeScript 5.0+支持),这样编译时会自动为导入添加正确的扩展名。
    2. 确保TypeScript版本至少为4.7,以支持nodenext模块解析策略。

解决问题1:顶层导入失败

  • 原因:package.json中main指向dist/index.js,但当前LIB的src目录没有顶层的index.ts文件,导致编译后dist目录下没有顶层index.js,自然没有对外导出的内容。
  • 修复方法:在LIB的src目录下创建顶层index.ts,导出需要对外暴露的组件:
    // src/index.ts
    export * from './container';
    
    这样tsc编译后会生成dist/index.js,其他项目就能通过import { Container } from '@company_name/LIB'正常导入。

关于内部组件导出的疑问

ContainerFooter仅作为Container的内部组件使用,确实不需要在container/index.ts中导出。对外暴露的index文件只需要导出外部项目需要使用的组件(比如Container),这样可以保持组件库的API简洁,避免暴露内部实现细节。

内容的提问来源于stack exchange,提问作者physicsboy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:15:09