Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot read properties of undefined (reading 'createContext') #63

Open
danthaiwang opened this issue Sep 14, 2023 · 5 comments
Open

Cannot read properties of undefined (reading 'createContext') #63

danthaiwang opened this issue Sep 14, 2023 · 5 comments

Comments

@danthaiwang
Copy link

Hello we're seeing an issue when consuming our toolkit library in a new project.

Screenshot 2023-09-14 at 15 27 17

I'll try to give a brief description of the project structure since it's quite big.

Our Component Toolkit Lib

This library contains lots of react components as well as Icons and is bundled and then consume via npm in the child application. The library is using styled-components and uses a ThemeProvider to wrap our application.

Since we're using many different Icons from phosphor and want to "theme" them in a common way, we created a component called Icon which accepts a recognised IconName. We then use that name to map it to an Icon within @phosphor/react

Example of our icon-map.ts file:

import { Armchair, Baby } from '@phosphor/react'

const iconMap: Record<IconName, Icon> = {
  armchair: Armchair,
  baby: Baby
}

export default iconMap

And then to consume these icons we look them up in the Icon.tsx file:

// This is a simplified version but the pattern is correct

type IconProps = {
  name: 'armchair' | 'baby'
  color: string
}

const Icon: FC<IconProps> = ({ name, color }) => {
  const Component = iconMap[name]
  
  return <Component color={color} />
}

The problem then occurs when we use our library in the consuming applications.

export const start = () => {
  ReactDOM.render(
    <ThemeProvider theme='default'>
      <div>This is our application</div>
    </ThemeProvider>,
    document.getElementById('root'),
  )
}

And then we see the problem. Any ideas?

These are the main versions we're using in our application:

"dependencies": {
  "@reduxjs/toolkit": "^1.9.5",
  "react": "^18.0.2",
  "react-dom": "^18.0.2",
  "react-redux": "^8.1.2",
  "@phosphor-icons/react": "^2.0.6"
},
"devDependencies": {
  "@babel/cli": "^7.21.0",
  "@babel/core": "^7.21.0",
  "@babel/plugin-proposal-class-properties": "^7.0.0",
  "@babel/plugin-proposal-decorators": "^7.8.3",
  "@babel/plugin-syntax-dynamic-import": "^7.0.0",
  "@babel/plugin-transform-runtime": "^7.21.0",
  "@babel/preset-env": "^7.20.2",
  "@babel/preset-react": "^7.18.6",
  "@babel/preset-typescript": "^7.21.0",
  "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
  "@types/node": "^20.5.9",
  "babel-loader": "8.1.0",
  "babel-plugin-import": "^1.13.6",
  "clean-webpack-plugin": "^4.0.0",
  "copy-webpack-plugin": "^11.0.0",
  "css-loader": "^6.7.3",
  "dotenv-webpack": "^8.0.1",
  "html-replace-webpack-plugin": "^2.6.0",
  "html-webpack-plugin": "^5.5.0",
  "mini-css-extract-plugin": "^2.7.2",
  "process": "0.11.10",
  "react-hot-loader": "^4.13.1",
  "react-refresh": "^0.14.0",
  "sass": "^1.66.1",
  "sass-loader": "^13.2.0",
  "tsconfig-paths-webpack-plugin": "^4.0.1",
  "typescript": "^5.2.2",
  "webpack": "^5.0.0",
  "webpack-cli": "^4.3.0",
  "webpack-dev-server": "^4.11.1",
  "webpack-merge": "^5.8.0"
}
@rektdeckard
Copy link
Member

rektdeckard commented Sep 14, 2023

The error indicates that the UMD bundle is being imported. I don't know exactly why this would cause issue, but it could be related. It may have something to do with the React peer dependency and your bundling process, because I read this error as saying "Webpack can't find the React import at runtime", and with UMD react libraries, React is expected to be available on the window object, IIRC.

Couple ideas:

You might want to try upgrading from 2.0.6 to 2.0.10, which has "type": "module" by default.

Try changing from import React from 'react' to import * as React from 'react' in your component lib, and/or adding "esModuleInterop": true and "allowSyntherocDefaultImports": true to your tsconfig there too, if not already present.

This isn't an error I have seen with Phosphor before, and it looks more like something with your bundling.

@danthaiwang
Copy link
Author

danthaiwang commented Sep 15, 2023

Hey - Thanks for your suggestions @rektdeckard

Unfortunately still not joy. I bumped to 2.0.10 but that had no affect.

I have been poking around with our tsconfig a bit but no avail. Perhaps if I drop it in here you could take a look and see if anything jumps out at you.

You suggestion to change the imports of react to import * as React... - I've tried that in my ThemeProvider.web.tsx file, but would you suggest doing this across the whole component library? There's about 100 components to make that change in, but I'd have thought doing in a single place would serve the purpose of the test.

{
  "include": ["src", "@types/**/*", "contracts"],
  "exclude": ["lib", "storybook/webpack.config.js", "./stories"],
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "declaration": true,
    "emitDeclarationOnly": false,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "module": "CommonJS",
    "isolatedModules": true,
    "jsx": "react",
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "moduleResolution": "node",
    "outDir": "lib",
    "noEmit": false,
    "resolveJsonModule": true,
    "rootDir": "./src",
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true,
    "target": "ES2015",
    "paths": {
      "contracts/*": ["contracts/*"]
    }
  },
}

@danthaiwang
Copy link
Author

Ok, so I've got it working... I'm cautious about calling it a total victory but it has unblocked me for what has been 3 days of not much fun.

I've added the minified React bundles to our html file in script tags and then added React to our webpack config as an externals prop.

// public/index.html

<script crossorigin src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
// webpack.common.js

externals: {
  React: 'react',
},

In your response when you said that the umd couldn't find React on the window, that pointed me down this route to look for a solution there, so thank you for that.

@rektdeckard
Copy link
Member

Just another thought, I see jsx: react in your config. Have you tried switching to jsx: react-jsx to use the automatic runtime? If not, React will need to be in scope in every file in your component library.

@rektdeckard
Copy link
Member

And in fact, in every consumer too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants