Rollup打包React TS组件后NPM导入报错问题排查
解决React TS组件NPM导入Jest报错问题
问题场景
用Rollup打包TypeScript编写的React组件MermaidDiagram发布到NPM后,通过命名导入import {MermaidDiagram} from "@lightenna/react-mermaid-diagram";时Jest报错:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
本地导入正常,NPM导入异常;尝试默认导入时获取到object类型,改为默认导出后类型文件types.d.ts为空。
核心原因
Rollup打包配置未兼顾ES模块与CommonJS的兼容导出,或TypeScript类型生成配置缺失,导致不同环境下模块解析异常。
解决方案
1. 调整Rollup打包配置,输出双格式模块
确保同时输出ES模块(供现代项目)和CommonJS模块(供Jest等默认使用CommonJS的环境):
// rollup.config.js import typescript from '@rollup/plugin-typescript'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; export default { input: 'src/index.ts', output: [ // CommonJS格式 { file: 'dist/index.cjs.js', format: 'cjs', sourcemap: true, exports: 'named' // 明确命名导出规则 }, // ES模块格式 { file: 'dist/index.esm.js', format: 'esm', sourcemap: true } ], plugins: [ resolve(), commonjs(), typescript({ tsconfig: './tsconfig.json', declaration: true, declarationDir: 'dist' }) ], external: ['react', 'react-dom'] // 排除React类依赖,避免打包进产物 };
同时在package.json中指定对应入口:
{ "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/types.d.ts", "type": "module" // 标记项目为ES模块规范 }
2. 修复TypeScript导出与类型生成
- 保持命名导出规范:在
src/index.ts中明确导出组件及类型:import React from 'react'; export interface MermaidDiagramProps { // 组件属性定义 } export const MermaidDiagram: React.FC<MermaidDiagramProps> = (props) => { // 组件实现逻辑 return <div>{/* 组件内容 */}</div>; }; - 调整TS配置确保类型生成:修改
tsconfig.json:{ "compilerOptions": { "declaration": true, "declarationDir": "./dist", "emitDeclarationOnly": false, "target": "ESNext", "module": "ESNext", "jsx": "react-jsx", "strict": true, "moduleResolution": "NodeNext", "esModuleInterop": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
3. 验证打包产物
执行打包命令后,检查dist目录下的文件:
index.cjs.js中需包含exports.MermaidDiagram = ...index.esm.js中需包含export const MermaidDiagram = ...types.d.ts中需正确导出组件类型:import React from 'react'; export interface MermaidDiagramProps { // 属性定义 } export declare const MermaidDiagram: React.FC<MermaidDiagramProps>;
4. 适配Jest模块解析
若项目使用ES模块规范,在jest.config.js中添加适配配置:
export default { transform: { '^.+\\.tsx?$': 'ts-jest' }, moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], extensionsToTreatAsEsm: ['.ts', '.tsx'], moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' } };
内容的提问来源于stack exchange,提问作者stanhope
相关产品推荐
相关产品推荐

