1

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 and rollup-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 in tsconfig.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.

Final notes

  • Just so things are clear, I have "main": "dist/index.js" in package.json in ui-component-lib.

Please let me know if you need more information to help me resolve this. Thank you all very much in advance.

Japorized
  • 11
  • 1
  • 1
  • Did you end up resolving this issue? – Doug Wilhelm Jul 24 '20 at 19:45
  • I'm not sure if I did end up finding a solution. Now that I know a little better though, maybe I should've specified the `module` property in `package.json` for the library file to point to the output that may be `index.esm.js`. Maybe try doing that? – Japorized Jul 25 '20 at 08:50

0 Answers0