npm-link 库上的挂钩调用无效
Invalid hook call on npm-link library
问题描述:
我目前正在创作一个名为 eformless
的包
我使用 CRA 创建了一个名为 sandbox
的目录,我在其中 link 编辑了包。
在尝试使用我正在尝试测试的 linked 包启动沙盒反应应用程序时,我不断收到以下错误:
// 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} />
)
}
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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
See altered link due to Whosebug ToS for tips about how to debug and fix this problem.
出现问题的地方:
问题似乎指向我的库,我在其中编写了一个使用从 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
捆绑了我的库
- 通过
npm link
在我的 eformless
库文件夹中创建了一个 link
- 并通过
npm link eformless
在我的 sandbox
文件夹中创建了 symlink
我尝试了什么:
我很自然地尝试通过错误消息中提供的 link 来解决问题。当 link 使用您自己的库时,这似乎是一个问题,如此处所述
This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.
我在我的 eformless
文件夹中做了 运行 npm link ../sandbox/node_modules/react
,但这似乎没有帮助,即使在关闭节点服务器并重新编译之后也是如此。
无论哪种方式,我都觉得很困惑,因为 运行nign npm ls react
只显示了一个版本的 React,它应该是有效的,因为 useState
被使用了 top-自定义挂钩内的级别。
重现问题
两个存储库都是 public
- You might have more than one copy of React in the same app See altered link due to Whosebug ToS for tips about how to debug and fix this problem.
这是因为您在 devDependencies
中对 eformless 做出了反应。这会导致您的应用程序 运行 两个 React 实例。
相反,移动对 eformless package.json
中的对等依赖项做出反应,删除您的 node_modules
目录和 运行 npm install
.
通过将 React 添加到对等依赖项,您是在通知模块打包器不要包含 React,而是期望依赖应用程序可以使用 React。
"peerDependencies": {
"react": "^16.13.1"
}
此外,我注意到您已将 node_modules
目录签入 eformless。你不应该那样做。相反,将 node_modules
添加到您的 .gitignore
文件中。
以防万一它对其他人有用,我已经在我的库中使用 React 作为 'peer dependency',但仍然遇到这个问题。
我必须执行以下步骤来解决它:
在图书馆:
- 如果您还没有这样做,请将生成问题的库设置为
package.json
中的 peerDependencies
而不是 dependencies
或 devDependencies
,例如在我的例子中 react
:
"peerDependencies": {
"react": "^16.8.6",
...
}
- 运行
npm install
- 构建库(在我的例子中,使用
rollup -c
npm 脚本)
在我的主应用程序中:
- 更改我的库的版本以指向我在
package.json
中具有相对路径的本地项目,例如
"dependencies": {
"my-library": "file:../../libraries/my-library",
...
}
将 resolve.symlinks = false
添加到我的主应用程序的 webpack 配置中
将 --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",
}
- 运行
npm install
- 运行
npm run start
另一种选择是在依赖应用程序的构建中使用 webpack alias
来删除 React 依赖项。
内部 webpack.config.js
应用程序使用链接依赖项:
resolve: {
alias: {
react: path.resolve(__dirname, '<app_path>/node_modules/react'),
'react-dom': path.resolve(__dirname, '<app_path>/node_modules/react-dom')
}
}
在您的主项目中使用别名。然后对于你的库,它将使用你的主项目的别名。
react : path.resolve(__dirname, './node_modules/react')
问题描述:
我目前正在创作一个名为
的包eformless
我使用 CRA 创建了一个名为
sandbox
的目录,我在其中 link 编辑了包。在尝试使用我正在尝试测试的 linked 包启动沙盒反应应用程序时,我不断收到以下错误:
// 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} /> ) }
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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app See altered link due to Whosebug ToS for tips about how to debug and fix this problem.
出现问题的地方:
问题似乎指向我的库,我在其中编写了一个使用从 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
捆绑了我的库
- 通过
npm link
在我的 - 并通过
npm link eformless
在我的
eformless
库文件夹中创建了一个 link
sandbox
文件夹中创建了 symlink
我尝试了什么:
我很自然地尝试通过错误消息中提供的 link 来解决问题。当 link 使用您自己的库时,这似乎是一个问题,如此处所述
This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.
我在我的 eformless
文件夹中做了 运行 npm link ../sandbox/node_modules/react
,但这似乎没有帮助,即使在关闭节点服务器并重新编译之后也是如此。
无论哪种方式,我都觉得很困惑,因为 运行nign npm ls react
只显示了一个版本的 React,它应该是有效的,因为 useState
被使用了 top-自定义挂钩内的级别。
重现问题
两个存储库都是 public
- You might have more than one copy of React in the same app See altered link due to Whosebug ToS for tips about how to debug and fix this problem.
这是因为您在 devDependencies
中对 eformless 做出了反应。这会导致您的应用程序 运行 两个 React 实例。
相反,移动对 eformless package.json
中的对等依赖项做出反应,删除您的 node_modules
目录和 运行 npm install
.
通过将 React 添加到对等依赖项,您是在通知模块打包器不要包含 React,而是期望依赖应用程序可以使用 React。
"peerDependencies": {
"react": "^16.13.1"
}
此外,我注意到您已将 node_modules
目录签入 eformless。你不应该那样做。相反,将 node_modules
添加到您的 .gitignore
文件中。
以防万一它对其他人有用,我已经在我的库中使用 React 作为 'peer dependency',但仍然遇到这个问题。
我必须执行以下步骤来解决它:
在图书馆:
- 如果您还没有这样做,请将生成问题的库设置为
package.json
中的peerDependencies
而不是dependencies
或devDependencies
,例如在我的例子中react
:
"peerDependencies": {
"react": "^16.8.6",
...
}
- 运行
npm install
- 构建库(在我的例子中,使用
rollup -c
npm 脚本)
在我的主应用程序中:
- 更改我的库的版本以指向我在
package.json
中具有相对路径的本地项目,例如
"dependencies": {
"my-library": "file:../../libraries/my-library",
...
}
将
resolve.symlinks = false
添加到我的主应用程序的 webpack 配置中将
--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",
}
- 运行
npm install
- 运行
npm run start
另一种选择是在依赖应用程序的构建中使用 webpack alias
来删除 React 依赖项。
内部 webpack.config.js
应用程序使用链接依赖项:
resolve: {
alias: {
react: path.resolve(__dirname, '<app_path>/node_modules/react'),
'react-dom': path.resolve(__dirname, '<app_path>/node_modules/react-dom')
}
}
在您的主项目中使用别名。然后对于你的库,它将使用你的主项目的别名。
react : path.resolve(__dirname, './node_modules/react')