I am developing an external component (let's say my-component
, which I link to the project with npm link
(as it is in process and I need the package to reflect changes).
In the my-component
folder there are node_modules/react
and node_modules/react-dom
as they are its dependencies. However they are peerDependences, so I did not suppose to bring them into the project linking this package.
However when using npm link
, it link the whole directory, including node_modules
. So, when the project builds, it includes packages 2 times: from node_modules/*
and from node_modules/my-component/node_modules/*
.
This begins to affect when the component is using ReactDOM.findDOMNode
, it causes this error:
Warning: React can't find the root component node for data-reactid value `.0.2.0`. If you're seeing this message, it probably means that you've loaded two copies of React on the page. At this time, only a single copy of React can be loaded at a time.
Also, it may help to understand what's happening: the problem only appears if there are both node_modules/my-component/node_modules/react
and node_modules/my-component/node_modules/react-dom
. If there is only one of them, there is no error message.
The usual package installation does not bring such error as there is no node_modules/react-dom
there.
How is it supposed to develop an external component and the project at the same time?
The problem is with npm link. https://github.com/npm/npm/issues/5875
npm doesn't treat the linked directory as a child of the parent project.
Try alternatives to npm link:
1) Use relative path dependencies in package.json
2) Manually include your dependencies in your projects node_modules directory
3) Use url path
Basically anything but npm link
The issue is twofold:
Solution:
All you have to do is link the react and react-dom in your component to that of parent project's node_modules folder.
Go to your component project and remove the react and react-dom then do
Someone clevererer than I (@mojodna) came up with this solution: remove the duplicate dependencies from the external component, and resolve them with your project's copies of those deps.
Step 1: Remove the dependencies from your external component's
node_modules
As @cleong noted, you can't just remove the deps from the external component's
node_modules
, because your project's build step will fail when it hits the now-missing dependencies in the external component.Step 2: Add your project's
node_modules
toNODE_PATH
To fix this, you can append the project's
node_modules
to theNODE_PATH
environment variable when running your build step. Something like e.g. this:NODE_PATH=$(pwd)/node_modules/ npm start
(where
npm start
is your script that bundles your external component, via e.g. Browserify, Webpack, etc.)In fact, you could always append that
NODE_PATH
addition to your build scripts, and it would work whether or not you'venpm link
ed anything. (Makes me wonder if it shouldn't be defaultnpm
behavior...)Note: I left my existing answer because there's some conversation there, and this is a different (and better) solution.