Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooks don't work with yarn link #14257

Closed
andy9775 opened this issue Nov 17, 2018 · 29 comments
Closed

Hooks don't work with yarn link #14257

andy9775 opened this issue Nov 17, 2018 · 29 comments

Comments

@andy9775
Copy link

@andy9775 andy9775 commented Nov 17, 2018

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
When developing an external library locally and using yarn link to link the library to a local react app the "hooks can only be called inside the body of a function component" error comes up. However, after publishing to npm and using the published version in the local react app everything works as expected.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

  1. Create a library that's built with hooks (my-hooks-lib)
  2. Create a local app that uses the library (my-react-app) using CRA
  3. yarn link in my-hooks-lib and in my-react-app run yarn link my-hooks-lib

What is the expected behavior?
yarn start in the react app should use hooks and render normally

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
react and react-dom 16.7.0-alpha.2
OSX

@gaearon
Copy link
Member

@gaearon gaearon commented Nov 19, 2018

It's not expected that it would work unless you link react back from your module to your app.

This has actually always been the case (React apps are subtly broken when there are two copies of React module). Hooks surface this immediately which I guess is good.

We do have another issue tracking a better error message for this case.

@gaearon gaearon closed this Nov 19, 2018
@andy9775
Copy link
Author

@andy9775 andy9775 commented Nov 22, 2018

My mistake - first time using yarn link with react. Thanks for addressing @gaearon

@corysimmons
Copy link

@corysimmons corysimmons commented Jun 28, 2019

Is there a workaround for this? How can people locally test react components they want to turn into libraries? :\


Workaround is https://github.com/whitecolor/yalc

@dcecile
Copy link

@dcecile dcecile commented Jul 5, 2019

If your React app is bundled with Webpack, you can use a Webpack alias to force all React references to resolve to a single module. In your webpack.config.js:

{
    /* ... */
    module: {
        rules: [ /* ... */ ],
    },
    resolve: {
        alias: { react: require.resolve("react") }
    },
}

(Solution from webpack/webpack#8607 (comment))

@maciekgrzybek
Copy link

@maciekgrzybek maciekgrzybek commented Jul 30, 2019

@dcecile just to clarify, do you resolve that in the library you're working? or in the demo app?

@dcecile
Copy link

@dcecile dcecile commented Jul 30, 2019

@maciekgrzybek I resolve it in the demo app

@maciekgrzybek
Copy link

@maciekgrzybek maciekgrzybek commented Jul 30, 2019

Hey @dcecile thanks for a quick answer, sadly, that doesn't work for me as well.

@LucidityDesign
Copy link

@LucidityDesign LucidityDesign commented Dec 19, 2019

I still get this error message even though I linked react and react-dom (via yarn link) and set react and react-dom as alias in my webpack.config:

'react': require.resolve('./node_modules/react'),
'react-dom': require.resolve('./node_modules/react-dom'),

@Blkc
Copy link

@Blkc Blkc commented Feb 19, 2020

Currently there are like 3 ways you can install local dependencies,

  1. yarn link
  2. yarn add
  3. yarn add .tgz file

npm pack on the library repository and yarn add .tgz file in the other repo seems to work for me. The other two give me the hook error.

@jerrygreen
Copy link

@jerrygreen jerrygreen commented Mar 5, 2020

Workaround:

cd PACKAGE_YOU_DEBUG_LOCALLY
yarn link
yarn install
cd node_modules/react
yarn link
cd ../../node_modules/react-dom
yarn link
cd YOUR_PROJECT
yarn link PACKAGE_YOU_DEBUG_LOCALLY
yarn link react
yarn link react-dom

I find it easier than some webpack setup or using yet another package manager (yapm? yanc? yalc? wut?)

@kas
Copy link

@kas kas commented May 27, 2020

If you're having this issue when developing a package that exports a React component, and you have a folder structure like this:

react-component-package/
  package.json
web-application/
  package.json

Assuming react-component-package has React as a dev and peer dependency, you can run this command from the react-component-package folder:
npm link ../web-application/node_modules/react

The same command should work with Yarn:
yarn link ../web-application/node_modules/react

https://stackoverflow.com/a/58612244

@danantal
Copy link

@danantal danantal commented Jun 3, 2020

Will this be addressed somehow? I guess there is an workaround - but when you use create react app you can't really do any hacks in the webpack.config.js 😄

@brennick
Copy link

@brennick brennick commented Sep 4, 2020

@jsmapr1
Copy link

@jsmapr1 jsmapr1 commented Sep 29, 2020

For those coming to the issue via a monorepo such as lerna, you can solve the problem by hoisting the dependencies to the root level.

#15097

@hugomallet
Copy link

@hugomallet hugomallet commented Oct 20, 2020

React is great for components but it looks like everything around react is preventing you from creating components.
Configuring bundlers and npm dependencies to work with external components is really a hell. And with CRA this is almost impossible.
I beg you, please find a solution to this ! Maybe from webpack 5 module federation ?

@DLCnow
Copy link

@DLCnow DLCnow commented Nov 4, 2020

Workaround:

cd PACKAGE_YOU_DEBUG_LOCALLY
yarn link
yarn install
cd node_modules/react
yarn link
cd ../../node_modules/react-dom
yarn link
cd YOUR_PROJECT
yarn link PACKAGE_YOU_DEBUG_LOCALLY
yarn link react
yarn link react-dom

I find it easier than some webpack setup or using yet another package manager (yapm? yanc? yalc? wut?)

It works! Tks!

@adamrneary
Copy link

@adamrneary adamrneary commented Mar 29, 2021

Thanks @jerrygreen!

For future explorers, the above solution didn't happen to work in my case. Not sure if it had to do with the use of NextJS, but that is possible!

A slight tweak worked, though: making the package link to my project's react and react-dom.

If you are in the same situation, perhaps try:

cd YOUR_PROJECT
cd node_modules/react
yarn link
cd ../react-dom
yarn link

cd PACKAGE_YOU_DEBUG_LOCALLY
yarn link
yarn install
yarn link react
yarn link react-dom

cd YOUR_PROJECT
yarn link PACKAGE_YOU_DEBUG_LOCALLY

This did the trick for us!

@jaguardo
Copy link

@jaguardo jaguardo commented May 4, 2021

does yalc help solve this. or complicate it more? I still seem to have the error, even with the work around.

@aud
Copy link

@aud aud commented May 4, 2021

@jaguardo in my experience Yalc removed a ton of the complexity that you would otherwise have to manage with symlinks yourself. Have been using it for a year or so now and the quality is very high. Worth giving it a shot for your use case.

@eric-burel
Copy link

@eric-burel eric-burel commented May 5, 2021

For googlers, this issue can also be encountered for project using Webpack 4 and transitionning to Webpack 5. If I sum it up, yalc link does the reverse of yarn link regarding node_modules, favouring those of the project that rely on the package to avoid duplicates? By the way Meteor works this way when using METEOR_PACKAGE_DIRS, which has always been extremely more intuitive than link.
If yes that would solve the issue more elegantly.

@regalstreak
Copy link

@regalstreak regalstreak commented May 8, 2021

Nothing worked but yalc for me

@L0rdH4x0r
Copy link

@L0rdH4x0r L0rdH4x0r commented May 11, 2021

Nothing from the above was needed! I got mine fixed by just keeping react and react-dom only as peerDependencies in package.json and delete all other occurrences. After that delete node_modules and package-lock.json and install again. Then in should work.

@eric-burel
Copy link

@eric-burel eric-burel commented May 11, 2021

Nothing from the above was needed! I got mine fixed by just keeping react and react-dom only as peerDependencies in package.json and delete all other occurrences. After that delete node_modules and package-lock.json and install again. Then in should work.

Most often, you cannot do this during development though, as you may need React for unit testing or 3rd party tools like Storybook. In a mono-repo, even if React is a peer-dependency of your package, it will fetch the "closest" version, so from your monorepo main node_modules instead of those from the app.
I've tested Yalc, with some success at the moment, though I am still not sure of the precise differences with a "normal" npm install.
This is how we intend to solve this for good in the future, taking inspiration from Meteor solution for this issue, based on an NPM_PACKAGE_DIRS environment variable: VulcanJS/vulcan-next#104

@austinrivas
Copy link

@austinrivas austinrivas commented May 11, 2021

yalc is the only solution to this problem (and the myriad of other issues caused by yarn/npm link) that consistently works.

Its pretty troubling that both yarn and npm seem convinced that naively symlinking entire directories ever worked.

@Omrilu-ma
Copy link

@Omrilu-ma Omrilu-ma commented May 27, 2021

Those who still struggling with the issue and work with react-scripts without eject do the following to solve the issue:

  1. yarn add @craco/craco
  2. Change the package.json start script

From:

   "start": "react-scripts start",

To

   "start": "craco start",
  1. Add craco.config.js file to your root application with the following content:
const path = require('path')

module.exports = {
    webpack: {
        alias: {
            react: path.resolve(__dirname, './node_modules/react'),
            'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
        },
    },
}

@alex-ds
Copy link

@alex-ds alex-ds commented Jul 2, 2021

In YOUR_PROJECT's package.json add into a jest config section:

...
  "jest": {
    "moduleNameMapper": {
        "^react$": "<rootDir>/node_modules/react",
        "^react-dom$": "<rootDir>/node_modules/react-dom"
    }
  }
...

It worked for me

@ramyNiranjan
Copy link

@ramyNiranjan ramyNiranjan commented Aug 8, 2021

Workaround:

cd PACKAGE_YOU_DEBUG_LOCALLY
yarn link
yarn install
cd node_modules/react
yarn link
cd ../../node_modules/react-dom
yarn link
cd YOUR_PROJECT
yarn link PACKAGE_YOU_DEBUG_LOCALLY
yarn link react
yarn link react-dom

I find it easier than some webpack setup or using yet another package manager (yapm? yanc? yalc? wut?)

It works! Tks!

@ramyNiranjan
Copy link

@ramyNiranjan ramyNiranjan commented Aug 8, 2021

This solution worked for me, Thanks a lot

@jquintozamora
Copy link

@jquintozamora jquintozamora commented Sep 22, 2021

I configured this in webpack 5 and it's working for me:

module.exports = {
  //...
  resolve: {
    symlinks: false,
  },
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet