5

I'm working on a component library that wraps some of the MaterialUI components and implements others to be used in a larger project. While setting up the library I had to setup webpack in order to be able to import and bundle images and css files in my library.

This library is located nested in the folder of the main project, where I add it as a dependency with npm i ./shared/path_to_library. this seems to work fine, since the typescript is working correctly and the npm start gives me no error. Then when I open it in a browser I get the following error page:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

But this error only occurs if I try to use any component from @mui/material inside my library. Exporting handmade components and using them in the main project works fine, but using any material component wrapped by my own component and then using it in the project brings me to this error. I also tried to move from webpack to rollup but I ended up getting the same problem.

Here are my config files for webpack and rollup:

rollup.config.js

import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import dts from "rollup-plugin-dts";

const pkg = require("./package.json");

const config = [
  {
    input: "src/index.ts",
    output: [
      { file: pkg.main, format: "cjs", sourcemap: true },
      { file: pkg.module, format: "esm", sourcemap: true },
    ],
    plugins: [
      resolve(),
      commonjs(),
      typescript({ tsconfig: "./tsconfig.json" }),
    ],
  },
  {
    input: "lib/esm/types/index.d.ts",
    output: [{ file: "lib/index.d.ts", format: "esm" }],
    plugins: [dts()],
  },
];

export default config;

webpack.config.js

const path = require("path");

module.exports = {
  entry: "./src/index.ts",
  mode: "development",
  output: {
    path: path.resolve(__dirname, "lib"),
    filename: "[name].js",
    libraryTarget: "umd",
    library: "my-core-library",
    umdNamedDefine: true,
  },
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.css?$/,
        use: ["style-loader", "css-loader"],
        exclude: /node_modules/,
      },
      {
        test: /\.tsx?$/,
        use: ["babel-loader", "ts-loader"],
        exclude: /node_modules/,
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: ["file-loader"],
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".jsx"],
  },
  externals: [
    {
      react: "react",
      "react-dom": "react-dom",
      "@mui/material": "@mui/material",
      "@emotion/react": "@emotion/react",
      "@emotion/styled": "@emotion/styled",
      "@mui/lab": "@mui/lab",
    },
  ],
};

I'm running out of ideas :(

2 Answers 2

1

This is probably happening because multiple instances of React are loaded. You can check with npm ls react, all react packages should be deduped

A short term solution is to link the react from the library, ie

npm link ../shared/path_to_library/node_modules/react

However you would have to re-link that everytime you install an npm package.

Sign up to request clarification or add additional context in comments.

Comments

0

I think you need to configure your .babelrc as following:

    "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript", "jest"],
    "plugins": [
        [
          "babel-plugin-transform-imports",
          {
            "@material-ui/core": {
              "transform": "@material-ui/core/${member}",
              "preventFullImport": true
            },
            "@material-ui/icons": {
              "transform": "@material-ui/icons/${member}",
              "preventFullImport": true
            }
          }
        ]
      ]

6 Comments

hmm that's a good suggestion, but it didn't fix it :( I even tried to manually change the imports of the @mui components to target only the component that I want, but I'm still getting the error
Interesting, did you check for mismatch between React and ReactDOM versions as suggested in the error? That usually causes the error you're getting.
I did and they're using the same versions. The closest that I got to fix was, when having the package nested in the bigger project, running npm install. this seemed to override some of the package dependencies with the main project's and fixed the issue, but as soon as I add any new dep to the package or run npm install again it stops working.
@ViniciusSouza, did you find a solution for this?
@ViniciusSouza did you solve this? I am having exactly same problem :(
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.