Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting error when using FormattedMessage inside a module: Error: [React Intl] Could not find required `intl` object

I have a monorepo which exposes a TypeScript module, which is consumed & used by a React TypeScript project.

When the module inserts arbitrary React elements to the virtual DOM - everything works as expected, including when I try to use React Router (which was initially problematic but I was able to fix that).

However, when I try to use react-intl, via FormattedMessage, I get the error:

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

Which is especially annoying as I see this printed in the console logs:

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)

(note the IntlProvider wrapping Loading - which is the element that uses FormattedMessage which can't find IntlProvider).

I imagine this is somehow related to versioning, or having 2 instances of React / React DOM / IntlProvider, but I have no idea to how solve this, and I have spent quite a lot of time trying everything I could think of.

For what it's worth, here's what I use:

  • TypeScript - for both module and project
  • Webpack to pack the module, where I declared React, ReactDOM and react-intl as externals and added them as peerDependencies rather than direct dependencies
  • create-react-app for the project

I was able to create a minimal repro repository, here's how to repro my issue:

<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

Anyone has any idea? Tons of thanks in advance!

like image 392
chakaz Avatar asked Aug 03 '20 05:08

chakaz


1 Answers

With your above way in order to make it work, you have to delete node_modules in your repro-lib dir cause it will install dependencies in both dirs.

So in order to resolve problem of monorepo, I'd like to suggest you use yarn's workspace functionality as described carefully here: https://classic.yarnpkg.com/en/docs/workspaces/

To summary, it's a great functionality to help working with multiple workspaces by just only yarn install once.

Here are a few steps to make your repo working:

  • Put package.json at the root level of the project with following content:
{
  "private": true,
  "workspaces": ["project", "repro-lib"]
}
  • Go to project dir and replace following line in package.json:
"pf-common": "file:../repro-lib"

to

"pf-common": "1.0.0" 
  • Finally, just go back to root top level install deps again:
yarn install

That's it! Now you can re-run your application to see how it works.

NOTE: In terms of having interest in monorepo, lerna is also great tool comes to help by providing great CLI.

like image 110
tmhao2005 Avatar answered Nov 15 '22 05:11

tmhao2005