mui / material-ui

Material UI: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Google's Material Design.
https://mui.com/material-ui/
MIT License
92.63k stars 31.92k forks source link

When trying to link an application using MUI v5, application gets "TypeError: Cannot read properties of null (reading 'useContext')" #42554

Closed MatTaNg closed 1 week ago

MatTaNg commented 1 month ago

Steps to reproduce

Link to live example: (required)

Steps:

  1. Copy the package.json, ErrorNotification and index.ts code below and put it in a new project
  2. Run yarn && rollup -c && npm link
  3. Create a new CRA project
  4. Modify app.js to import ErrorNotification
  5. Run yarn && npm link @xxxx/ui-shared-library && npm run start

Current behavior

We are trying to use MUI in our shared library to create shared components for our applications. Our shared application is working fine when it is imported from artifactory and within the shared repo as well.

We have recently decided to locally link our shared repo with our application using yarn link however, we keep running into this error below in applications that use our shared library:

Screenshot 2024-06-06 at 4 09 30 PM

I spun up a CRA and just linked the shared library to create a minimal environment The only code I modified in the CRA is App.js, I have highlighted the modified code below:

import logo from "./logo.svg";
import "./App.css";
import { ErrorNotification } from "@xxxx/ui-shared-library"; // <-- Modified

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          <ErrorNotification></ErrorNotification> // <-- Modified
        </a>
      </header>
    </div>
  );
}

export default App;

This is simply to import a component in our shared library. This is what ErrorNotification looks like in our shared repo:

import React from "react";
import { Snackbar, Alert } from "@mui/material";

type ErrorNotificationProps = {
  message?: string;
};

const DEFAULT_ERROR_MESSAGE =
  "Oops! Something went wrong, please try again later.";
const AUTO_HIDE_DURATION = 6000;

export const ErrorNotification = (props: ErrorNotificationProps) => {
  return (
    <Snackbar open={true} autoHideDuration={AUTO_HIDE_DURATION}>
      <Alert severity="error">{props.message ?? DEFAULT_ERROR_MESSAGE}</Alert>
    </Snackbar>
  );
};

Then we export our ErrorNotification in src/index.ts

import { ErrorNotification } from "./Notifications";

export { ErrorNotification };

Here is our package.json in our shared library:

{
  "name": "@xxxx/ui-shared-library",
  "version": "1.0.0",
  "main": "dist/index.js",
  "files": [
    "dist"
  ],
  "private": false,
  "peerDependencies": {
    "@emotion/react": "^11.11.4",
    "@emotion/styled": "^11.11.0",
    "@floating-ui/react-dom": "^2.0.8",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "web-vitals": "^2.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "rollup src/App.tsx --format iife --name ui-shared-library --file bundle.js ",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest",
      "plugin:storybook/recommended"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "publishConfig": {
    "registry": "xxxx"
  },
  "strict-ssl": false,
  "devDependencies": {
    "@babel/core": "^7.20.5",
    "@babel/preset-env": "^7.21.4",
    "@babel/preset-react": "^7.18.6",
    "@babel/preset-typescript": "^7.23.3",
    "@mui/material": "^5.15.19",
    "@mui/icons-material": "^5.3.1",
    "@rollup/plugin-commonjs": "^25.0.7",
    "@rollup/plugin-node-resolve": "^15.2.3",
    "@storybook/addon-essentials": "^7.5.3",
    "@storybook/addon-interactions": "^7.5.3",
    "@storybook/addon-links": "^7.5.3",
    "@storybook/addon-onboarding": "^1.0.8",
    "@storybook/blocks": "^7.5.3",
    "@storybook/preset-create-react-app": "^7.5.3",
    "@storybook/react": "^7.5.3",
    "@storybook/react-webpack5": "^7.5.3",
    "@storybook/testing-library": "^0.2.2",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^13.0.0",
    "@testing-library/user-event": "^13.2.1",
    "@types/jest": "^27.0.1",
    "@types/node": "^16.7.13",
    "@types/react": "^18.2.18",
    "@types/react-dom": "^18.2.7",
    "babel-loader": "^9.1.3",
    "babel-plugin-named-exports-order": "^0.0.2",
    "eslint-plugin-storybook": "^0.6.15",
    "prettier": "3.1.0",
    "prop-types": "^15.8.1",
    "react-scripts": "5.0.0",
    "rollup": "^2.79.1",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-sass": "^1.12.21",
    "rollup-plugin-typescript": "^1.0.1",
    "rollup-plugin-typescript2": "^0.36.0",
    "sass": "^1.69.5",
    "storybook": "^7.5.3",
    "tslib": "^2.6.2",
    "typescript": "4.8",
    "webpack": "^5.89.0"
  }
}

We use rollup to create our dist folder: rollup.config.mjs:

import nodeResolvePlugin from "@rollup/plugin-node-resolve";
import { readFileSync } from "fs";
import { defineConfig } from "rollup";
import PeerDepsExternalPlugin from "rollup-plugin-peer-deps-external";
import typescript from "rollup-plugin-typescript";
import sassPlugin from "rollup-plugin-sass";
import commonjsPlugin from "@rollup/plugin-commonjs";

const packageJson = JSON.parse(
  readFileSync("./package.json", { encoding: "utf8" })
);

const config = defineConfig({
  input: "./src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "es",
      sourcemap: true,
    },
  ],

  plugins: [
    PeerDepsExternalPlugin(),
    nodeResolvePlugin(),
    commonjsPlugin(),
    sassPlugin({
      insert: true,
    }),
    typescript(),
  ],
});

export default config;

Once the environment is set up what we've been doing is in our shared repo we'd run: yarn rollup -c npm unlink @xxxx/ui-shared-library npm link

Then in the CRA app: npm unlink @xxxx/ui-shared-library npm link @xxxx/ui-shared-library npm run start

Expected behavior

Applications should be able to successfully link to our shared repo for local development

Context

We are trying to link our shared repo with our application locally so changes are instantly reflected on our applications

Your environment

npx @mui/envinfo ``` System: OS: macOS 14.5 Binaries: Node: 18.14.2 - ~/.nvm/versions/node/v18.14.2/bin/node npm: 9.5.0 - ~/.nvm/versions/node/v18.14.2/bin/npm pnpm: Not Found Browsers: Chrome: Not Found Edge: Not Found Safari: 17.5 npmPackages: @emotion/react: 11.11.4 @emotion/styled: 11.11.5 @mui/base: 5.0.0-beta.40 @mui/core-downloads-tracker: 5.15.19 @mui/icons-material: ^5.3.1 => 5.15.19 @mui/material: ^5.15.19 => 5.15.19 @mui/private-theming: 5.15.14 @mui/styled-engine: 5.15.14 @mui/system: 5.15.15 @mui/types: 7.2.14 @mui/utils: 5.15.14 @types/react: ^18.2.18 => 18.3.3 react: 18.3.1 react-dom: 18.3.1 typescript: 4.8 => 4.8.4 ```

Testing on Chrome v125.0.6422.77

Search keywords: useContext, Invalid hook call, npm link, yarn linkn

ZeeshanTamboli commented 1 month ago

Code snippets alone won't help us debug the issue, as the pasted code might differ from your actual code. Please provide a minimal reproduction in a GitHub repository. You can create two separate repositories: one for your shared library and another for your React app.

MatTaNg commented 3 weeks ago

Here is the dummy app that uses the shared library: https://github.com/MatTaNg/link-test

Here is a dummy shared library: https://github.com/MatTaNg/ui-shared-library

Steps to repo: 1) Run npm install on both repos 2) rollup -c && npm link on ui-shared repo 3) npm link ui-shared-library on link-test repo 4) Run npm run start on link-test repo 5) Observe useContext error

Removing material from Error Notification component makes the error go away

ZeeshanTamboli commented 3 weeks ago

@MatTaNg I encountered the following error when running rollup -c in your ui-shared-library:

[!] RollupError: node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.d.mts (38:12): Expected ',', got '*' (Note that you need plugins to import files that are not JavaScript)
node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.d.mts (38:12)
36: import { Platform } from '@floating-ui/dom';
37: import { platform } from '@floating-ui/dom';
38: import type * as React from 'react';
                ^
39: import { Rect } from '@floating-ui/dom';
40: import { ReferenceElement } from '@floating-ui/dom';
RollupError: Expected ',', got '*'

Additionally, I noticed that @mui/material is listed as a dev dependency in your package.json. It should be installed as a regular dependency like @emotion/styled. Also, @emotion/react is missing from your shared library dependencies. See the installation docs.

MatTaNg commented 2 weeks ago

I updated the ui-shared-library, it should be working now https://github.com/MatTaNg/ui-shared-library https://github.com/MatTaNg/link-test

^ Use the same repo steps as above

I moved material into dependencies and installed @emotion/styled and @emotion/react

ZeeshanTamboli commented 2 weeks ago

I am still getting the same error as https://github.com/mui/material-ui/issues/42554#issuecomment-2198030215 when I run rollup -c on ui-shared-library.

MatTaNg commented 2 weeks ago

I just cloned the ui-shared-repo and did a rollup -c and it worked for me. The exact steps I ran are: 1) git clone https://github.com/MatTaNg/ui-shared-library.git (cd into dir) 2) npm install 3) rollup -c

Are you running these steps exactly?

ZeeshanTamboli commented 2 weeks ago

Are you running these steps exactly?

Yes. See screen recording:

https://github.com/mui/material-ui/assets/20900032/f445c6c3-ed9c-4118-a513-ab8fa89cc955

github-actions[bot] commented 1 week ago

Since the issue is missing key information and has been inactive for 7 days, it has been automatically closed. If you wish to see the issue reopened, please provide the missing information.