I've been trying to set up a UI Component library that uses React and TypeScript. The expectation is that I can have my UI component library separated from Project B, which is a multi-repo project, so that each of the projects in Project B can import the library as a dependency.
I've been running into the following error repeatedly so.
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.
My repo structure looks something like the following.
ui-component-lib
|- package.json
|- tsconfig.json
|- src
|- index.ts
|- components
|- Button
|- index.ts
|- Menu
|- index.ts
src/components/Button/index.ts
:
import * as React from 'react';
export default class Button extends React.Component {
render() {
return <button>Button</button>;
}
}
src/index.ts
:
export * from './components/Button';
export * from './components/Menu';
tsconfig.json
:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": false,
"jsx": "react",
"lib": [
"esnext",
"dom"
],
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"pretty": true,
"removeComments": false,
"strict": true,
"target": "esnext",
"useDefineForClassFields": false,
"composite": true,
"declarationMap": true,
"emitDeclarationOnly": false,
"sourceMap": true,
"outDir": "dist",
"declarationDir": "dist",
"rootDir": "src"
},
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"src/**/*.test.tsx",
"src/**/*.test.ts"
]
}
I've been importing my components like so:
import { Menu, Button } from 'ui-component-lib';
Things I've tried
- I'm using Webpack with
ts-loader
to compile, and the configuration there is standard. I've also tried using Rollup and the plugins for Typescript there (@rollup/plugin-typescript
androllup-plugin-typescript2
), just to make sure that it's not a problem with the build process. So I'm guessing it's an issue with either the code or the compilation configurations. - Tried setting
allowSyntheticDefaultImports
intsconfig.json
to be false, cause that worked for some people (through digging around Github issues and here), but it did not work for me. - Tried reading through and experimenting with the configs of other similar projects (e.g. Blueprint) but no dice.
- Tried setting up an MWE for
ui-component-lib
, and let be Project B created using create-react-app (with TS), but I error I got was
JSX element type Button does not have any construct or call signatures.
- Checked Github issues and SE for similar issues:
- React.createElement: type is invalid — expected a string made sure to use
export default
- Element type is invalid: expected a string (for built-in components) or a class/function Yep, using
import { Button } from 'lib'
and notimport Button from 'lib'
- https://github.com/facebook/react/issues/12214
- microsoft/TypeScript #14558
- React.createElement: type is invalid — expected a string made sure to use
Final notes
- Just so things are clear, I have
"main": "dist/index.js"
inpackage.json
inui-component-lib
.
Please let me know if you need more information to help me resolve this. Thank you all very much in advance.