Andrew Medhurst
Andrew Medhurst

Reputation: 133

Resolving duplicate React implementations when using NPM Link on a React Component Library package

Got a question about how best to symlink a React component library NPM package to a parent/consuming React project.

The component library in question works without issue when build and publishing it to an external package registry, such as Artifactory. It is able to be imported and leveraged with no errors. However, for the sake of ease of development locally, I'd very much link to create a symlink of this package, which can then be linked to a consuming location (other React project).

Sounds basic enough, right? We've all had to npm link something before, right? Wrong. I go through the steps, yarn everything up on the destination project, serve the app, and BAM!

TypeError
Cannot read properties of null (reading 'useState')
Call Stack
 Object.eval [as useState]
  library-package/dist/index.es.js:31:30128
 PP
  library-package/dist/index.es.js:109:22535
 renderWithHooks
  node_modules/react-dom/cjs/react-dom.development.js:15486:18
 mountIndeterminateComponent
  node_modules/react-dom/cjs/react-dom.development.js:20098:13
 beginWork
  node_modules/react-dom/cjs/react-dom.development.js:21621:16
 HTMLUnknownElement.callCallback
  node_modules/react-dom/cjs/react-dom.development.js:4164:14
 HTMLUnknownElement.nrWrapper
  react:16:18275
 Object.invokeGuardedCallbackDev
  node_modules/react-dom/cjs/react-dom.development.js:4213:16
 invokeGuardedCallback
  node_modules/react-dom/cjs/react-dom.development.js:4277:31
 beginWork$1
  node_modules/react-dom/cjs/react-dom.development.js:27485:7

I now understand that React gets "confused" when there are two different versions of React. I've also come to understand that npm link-ing something does not honor what is declared in peerDependencies of the aforementioned component library.

At first, I just made sure that both the package and destination were both using v18.3.0 (the version I'm using, obviously) of both the react and react-dom packages, because there appeared to be a discrepancy there. No luck after solving the mismatch. Still busted.

So, I then attempted to implement the solution listed at the post here. I completely removed both react and react-dom from the library package, and then symlinked to each of those packages that exist in the destination's node_modules folder. Example: from the library package's directory npm link <relative-path-from-package-to-destination>/node_modules/react, then doing the same for react-dom. I then yarn-ed everything up, and validated that the paths to those packages where good to go with npm ls <package-name>. Everything checked out.

Surely, this means that both the destination and package would be using a singular version and location of react / react-dom. To be extra sure, I even set the version of both packages to version 18.3.0 in the resolutions block within the package.json of both the destination and package.

...I got the same error.

So I checked out the browser's console, and saw this:

1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. 
Error Component Stack
    at PP (index.es.js:23897:988)
    ...

My thoughts to each of the 3 points are as follows:

  1. Doubtful. I ran npm ls react (same for react-dom), and everything, including dependencies is using v18.3.0.
  2. Doubtful. This package works like a dream when added from a package directory.
  3. Probably? I don't know how to make it more specific than what I did to symlink to the destination React project's implementation of React, though.

Please tell me what I'm trying to do is achievable, and if so not through something like Verdaccio. While a local registry does enable local development in the sense that you don't have to package and deploy to, say, Artifactory, it does still require versioning up the package, and deploying it to somewhere. This is a clunky, cumbersome process that slows local development, and I'd like to avoid it with npm link if possible. Thanks in advance!

Upvotes: 0

Views: 56

Answers (0)

Related Questions