npm-link库上无效的挂钩调用

时间:2020-10-09 16:21:00

标签: node.js reactjs typescript npm npm-link

问题描述:

  • 我当前正在编写一个名为eformless

    的软件包
  • 我已经使用CRA创建了一个名为sandbox的目录,在其中链接了程序包。

  • 当尝试使用要测试的链接程序包启动沙箱react应用程序时,出现以下错误:

    // inside my 'sandbox' App.tsx
    import React from 'react'
    import { useField } from 'eformless'
    
    const App = () => {
      const [test, handleChange] = useField('testing')
      return (
        <input type="text" value={test.value} onChange={handleChange} />
      )
    }
    

错误:无效的挂钩调用。挂钩只能在功能组件的主体内部调用。发生这种情况可能是由于以下原因之一:

  1. 您可能使用了不匹配的React和渲染器版本(例如React DOM)
  2. 您可能正在违反挂钩规则
  3. 您可能在同一应用中拥有多个React副本 有关如何调试和解决此问题的提示,请参见altered link due to stackoverflow ToS

发生问题的地方:

问题似乎指向我的库,在这里我编写了一个使用从React导入的钩子的自定义钩子。
这是我的代码中有问题的摘录:

export const useField = <T>(
  input: T
  ...checkFunctions: Array<(...args: unknown[]) => unknown>
): [FieldType<T>, FieldHandlerFunction<T>, FieldHandlerFunction<T>] => {
  const [value, setValue] = useState(input)
  const [name, setName] = useState('')
  // Issue seems to be here ^
}

我的设置相当正常,并且似乎在其他项目中也能正常工作

  • 首先,我通过rollup -c捆绑了我的图书馆
  • 通过eformless在我的npm link库文件夹中创建了一个链接
  • 并通过sandbox在我的npm link eformless文件夹中创建符号链接

我尝试过的事情:

我自然尝试通过错误消息中提供的链接来解决此问题。链接您自己的库时,这似乎是一个问题,如此处所述

当您使用npm链接或等效链接时,也会出现此问题。在这种情况下,您的捆绑程序可能会“看到”两个Reacts-一个在应用程序文件夹中,一个在您的库文件夹中。假设myapp和mylib是同级文件夹,一种可能的解决方法是从mylib运行npm link ../myapp/node_modules/react。这应该使库使用应用程序的React副本。

我确实在我的npm link ../sandbox/node_modules/react文件夹中运行了eformless,但是即使关闭节点服务器并重新编译后,这似乎也无济于事。

无论哪种方式,这对我来说都确实令人困惑,因为运行npm ls react仅显示单个版本的react,并且应该有效,因为useState是在自定义钩子中顶层使用的。 / p>

再现问题

两个存储库都是公开的

2 个答案:

答案 0 :(得分:2)

以防万一它对其他人有用,我已经在我的库中使用 react 作为“对等依赖项”,但仍然遇到此问题。

我必须执行以下步骤来解决它:

在图书馆

  1. 如果您还没有这样做,请将产生问题的库设置为 peerDependencies 中的 package.json 而不是 dependenciesdevDependencies,例如就我而言react
"peerDependencies": {
  "react": "^16.8.6",
  ...
}
  1. 运行npm install
  2. 构建库(就我而言,使用 rollup -c npm 脚本)

在我的主应用中

  1. 更改我的库版本以指向我在 package.json 中具有相对路径的本地项目,例如
"dependencies": {
  "my-library": "file:../../libraries/my-library",
  ...
}
  1. resolve.symlinks = false 添加到我的主应用程序的 webpack 配置

  2. --preserve-symlinks-main--preserve-symlinks 添加到我的 package.json 启动脚本中,例如:

"scripts": {
  "build": "set WEBPACK_CONFIG_FILE=all&& webpack",
  "start": "set WEBPACK_CONFIG_FILE=all&& webpack && node --preserve-symlinks-main --preserve-symlinks dist/server.js",
}
  1. 运行npm install
  2. 运行npm run start

答案 1 :(得分:1)

  1. 您可能在同一应用程序中拥有多个React副本。有关如何调试和修复此问题的提示,请参见由于stackoverflow ToS而更改的链接。

这是因为您在devDependencies中对无格式有反应。这将导致您的应用程序运行React的两个实例。

相反,对eformless package.json中的对等依赖项做出反应,删除您的node_modules目录,然后运行npm install。

通过添加对同等依赖项的响应,您是在通知模块捆绑程序不包括react,而是希望依赖应用程序可以对其使用React。

"peerDependencies": {
  "react": "^16.13.1"
}

此外,我注意到您已将node_modules目录检入到无格式。你不应该那样做。而是将node_modules添加到您的.gitignore文件中。

相关问题