在模块中使用 FormattedMessage 时出错:错误:[React Intl] 找不到所需的 `intl` 对象

Posted

技术标签:

【中文标题】在模块中使用 FormattedMessage 时出错:错误:[React Intl] 找不到所需的 `intl` 对象【英文标题】:Getting error when using FormattedMessage inside a module: Error: [React Intl] Could not find required `intl` object 【发布时间】:2020-11-23 05:01:45 【问题描述】:

我有一个暴露 TypeScript 模块的 monorepo,它被 React TypeScript 项目消耗和使用。

当模块将任意 React 元素插入到虚拟 DOM 时 - 一切都按预期工作,包括当我尝试使用 React Router 时(最初是有问题的,但我能够修复它)。

但是,当我尝试通过 FormattedMessage 使用 react-intl 时,出现错误:

Error: [React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.

当我在控制台日志中看到这一点时,这尤其令人讨厌:

The above error occurred in the <Context.Consumer> component:
    in FormattedMessage
    in h2
    in div
    in Loading (at App.tsx:11)
    in IntlProvider (at App.tsx:8)
    in App (at src/index.tsx:9)
    in StrictMode (at src/index.tsx:8)

(注意 IntlProvider 包装 Loading - 这是使用 FormattedMessage 的元素,但找不到 IntlProvider)。

我想这在某种程度上与版本控制有关,或者有 2 个 React / React DOM / IntlProvider 实例,但我不知道如何解决这个问题,我花了很多时间尝试我能想到的一切。

对于它的价值,这是我使用的:

TypeScript - 适用于模块和项目 Webpack 打包模块,我将 React、ReactDOM 和 react-intl 声明为 externals 并将它们添加为 peerDependencies 而不是直接依赖项 create-react-app 代表项目

我能够创建一个最小的 repro 存储库,这里是如何重现我的问题:

<cd somewhere>
git clone https://github.com/chakaz/repro-repo .
cd repro-lib
npm install
npm run build:dev
cd ../project
npm install
npm run start

有人知道吗?提前致谢!

【问题讨论】:

【参考方案1】:

为了使它工作,你必须在repro-lib 目录中删除node_modules,因为它会在两个目录中安装依赖项。

所以为了解决monorepo的问题,我建议你使用yarn的工作区功能,这里仔细描述:https://classic.yarnpkg.com/en/docs/workspaces/

总而言之,只需yarn install 一次即可帮助处理多个工作区,这是一项很棒的功能。

以下是使您的回购工作的几个步骤:

package.json放在项目的根目录,内容如下:

  "private": true,
  "workspaces": ["project", "repro-lib"]

转到project 目录并替换package.json 中的以下行:
"pf-common": "file:../repro-lib"

"pf-common": "1.0.0" 
最后,再次回到 root ***安装部门:
yarn install

就是这样!现在您可以重新运行您的应用程序,看看它是如何工作的。

注意:就对 monorepo 感兴趣而言,lerna 也是通过提供出色的 CLI 来提供帮助的绝佳工具。

【讨论】:

谢谢谢谢谢谢谢谢!我被困在这个问题上的时间比我想承认的要多。出于好奇,因为这确实解决了我的问题 - 为什么 react-intl 有错误,但其他反应元素(使用 react 和 react-dom)工作正常? 我认为问题在于我们有 2 个实例,不仅有 react-intl,还有 react,所以它们是分开的,最终它们彼此不理解。 但是——“其他”react(我从未调用过 ReactDOM.render() 的库所使用的那个)是如何工作的? 个人拥有两个 React 实例除了在构建时拥有一个大包之外不会产生太多问题。真正的问题是 react-intl 在拥有多个实例方面不起作用。

以上是关于在模块中使用 FormattedMessage 时出错:错误:[React Intl] 找不到所需的 `intl` 对象的主要内容,如果未能解决你的问题,请参考以下文章

React-intl const <FormattedMessage /> 给出 [object object] 作为结果

[React Intl] Render Content with Placeholders using react-intl FormattedMessage

使来自 react-intl 的 FormattedMessage 中的 id 继承自自定义 TypeScript 接口以启用 VS IntelliSense 和类型检查

Bootstrap 手风琴在打字稿中不起作用

[react] React Intl是什么原理?

多语言 button