2
votes

UPDATE:

Solved. Hooks work fine in a simple mono repo setup, but there must be some module resolution issue with the more complicated mono repo I'm working with.

Here is a working example with a CRA app, TypeScript component, in a Lerna mono repo with the component and app using hooks: https://github.com/adamplabarge/react-lerna-hooks

END UPDATE

SECOND UPDATE

I updated the real app I'm working on to resolve react and react-dom to the same place. Since it is a CRA app I had to use customize-cra and added

  addWebpackAlias({
    ['react$']: path.resolve(__dirname, './node_modules/react/'),
    ['react-dom$']: path.resolve(__dirname, './node_modules/react-dom/')
  })

END SECOND UPDATE

I want to be able to develop a React component with Hooks inside another existing React app.

I have the repo setup with Lerna, and have /packages/app and /packages/component.

I can start the app (which is a CRA app) with $ yarn start and I run a build and watch script for the component (not CRA, just a normal TypeScript React component) which uses a webpack config to build and output a umd file at /packages/component/build/index.js. With the package.json in the component "main": "build/index.js".

By adding the component to the app's package.json dependencies, Lerna creates a link to the component and I can use it in the app via the normal import process.

This works great until adding a hook where it chokes on the multiple Reacts issue.

The only way I have been able to get this to work is by adding React & ReactDOM to the root level node_modules and deleting those packages from /packages/app/node_modules & /packages/component/node_modules. When I do this, both the app and component resolve the React and ReactDOM packages at the root level, being the exact same package. Also the exact same path to the packages.

I have tried setting externals key in the component's webpack config file. I have tried setting it in many different ways and with other externals plugins. I have tried resolving react as an alias to the react package in /packages/app/node_modules/react. I have even tried setting file:{the path} in the package.json instead of a version. I have also tried using the resolutions key in the package.json of the component.

Nothing has worked. The only way I can get this to work while using hooks is to delete react and react-dom from the node_modules in both /packages/app/node_modules and /packages/component/node_modules and only have it at /root/nodule_modules where package.json and lerna.json are setup.

I would like to be able to get this working w/o manually deleting the react and react-dom from each lerna package's node_modules.

Also have verified that each version of react is the same, and that the rules of hooks are not being violated. It works when the lerna packages literally resolve to the same /react/ package in the whole repo.

I have also tried setting up the React packages in the /packages/component/ to either be peerDependencies and or devDependencies. Didn't make a difference.

It seems like the only way to get hooks to work is when both app and component find react at the same path. like C:\project\node_modules\react

Suggestions? Questions? This is driving me nuts!

1
Thanks a lot for such a detailed explanation. Until now I've felt like I'm the only unlucky person who faced this issue :) Moving "react" and "react-dom" to the root dir really solves the problem but I was also searching for a more practical solution. - Max Donchenko

1 Answers

0
votes

Old question but no answer, so here's my take.

I had the same issue with my setup:

  • lerna monorepo
  • multiple packages (some with simple JS classes, others with React components)
  • a React app

I solved my problem by simply doing the following in all my React components' folders:

npm link <path to my app's folder>/node_modules/react

This command allows my React components to use the React instance of my app.