在monorepo(turborepo和npm工作区)中从共享组件库导入React组件时出现“Error: Invalid hook call.”错误。

7

我一直在建立一个monorepo,目的是创建一个共享组件库,用于多个不同的Next.js应用程序(遵循这个例子),但每当我从共享库中导入一个组件时,我都会得到以下错误:

Unhandled Runtime Error
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
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
  1. 在函数组件主体内调用了钩子(useState)。如果我从与项目相同的文件夹中导入它,则该组件可以正常工作。
  2. 再次提醒,本地环境下没有问题。
  3. 据我所见,我在单库存储库的根目录中只有一个版本的react和react-dom,均为v. 17.0.2。我的共享组件包中将react和react-dom设置为对等依赖项。

我认为这可能与我在组件内使用的mui组件有关,因为可以毫无问题地导入并使用这个组件:

    // TestComponent.jsx

    import * as React from 'react';

    export const TestComponent = () => {
      return <h1>test</h1>;
    };

但是这个会抛出“无效的钩子”错误:
    // TestButton.jsx

    import * as React from 'react';
    import { Button } from '@mui/material';

    export const TestButton = () => {
      return <Button>Boop</Button>;
    };

这是我共享组件包的package.json文件:

{
  "name": "shared-components",
  "version": "0.0.0",
  "main": ".dist/index.js",
  "module": "./dist/index.mjs",
  "sideEffects": false,
  "license": "MIT",
  "files": [
    "dist/**"
  ],
  "scripts": {
    "build": "tsup src/index.jsx --format esm,cjs --external react",
    "dev": "tsup src/index.jsx --format esm,cjs --watch --external react",
    "lint": "TIMING=1 eslint src --fix",
    "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
  },
  "devDependencies": {
    "tsup": "^5.10.1"
  },
  "peerDependencies": {
    "@mui/icons-material": "^5.6.1",
    "@mui/material": "^5.6.1",
    "@mui/utils": "^5.6.1",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  }
}

我已将以下内容添加到我的 next.config.js 文件中,以便在项目中使用共享组件:

const withTM = require('next-transpile-modules')(['shared-components']);

module.exports = withTM({
  reactStrictMode: true,
});
1个回答

0

终于解决了...

我不得不在我的消费者网站的next.config.js中添加这个

const withTM = require('next-transpile-modules')(['shared-components'], { resolveSymlinks: false });

module.exports = withTM({
  reactStrictMode: true,
});

尽管next-transpile-modules的文档说对于npm工作区,resolveSymlinks应该默认为true,但将其设置为false是唯一有效的方法。

如果有人能够向我澄清为什么这样做可以起作用,我很乐意学习,但现在它按预期工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接