Reputation: 61
I am running into the following problem when trying to develop a React component library using styled-components
.
For the purpose of this example, let's assume we have two repos, app
and core
and that core
will be consumed by app
.
Currently, core
is written in TypeScript and built using tsc
.
In order to rapidly iterate, I attempted to use yarn link
to link core
into app
.
This works fine for making app
find core
... the problem I'm facing is when the compiled TypeScript code of core
attempts to require a package, say styled-components
, it attempts to find this package in the node_modules
of core
(not of app
). Since I have styled-components
as both a peerDependency and devDependency it is able to find it in core
's node_modules
, but this is not what I want to happen. I would like it to use the styled-components
of app
.
One alternative to yarn link
I have tried is by adding the dependency of core
to app
via file:/path
. This seems to work as expected, but introduces new problems. How can I have a path of my dev machine existing in the package.json
just for local development (without constantly switching it back and forth)? Also, it seems any updates made in core
require the package to be removed from app
, and have yarn's cache cleared before re-adding it.
Is there any simpler way to make this scenario work? I've just started looking at Rollup or Webpack as a solution, but not sure if that is the right direction.
Upvotes: 5
Views: 10096
Reputation: 25072
I had a similar issue where adding a package via yarn link
to a project would break unrelated things (whereas the two projects worked fine on their own, or if I'd use the package without yarn link
).
I think it's because the linked package's dependencies will take priority (possibly this issue) and they used different versions than my main app's dependencies. I.e. I had "typescript": "^4.2.3"
in my main app but "typescript": "^4.6.3"
in the linked package. The ^
would allow my main app to resolve this dependency to the version in the linked package, breaking typescript in the main app. This was confusing because there was no change in the main project's yarn.lock
that would indicate that the typescript
version changed.
I got around this by having exact dependencies in the main project. I.e. "typescript": "4.2.3"
. I don't think this solves the root cause but it makes sure I know exactly which dependency is loaded, in which case I don't care where it is loaded from.
Upvotes: 0
Reputation: 3211
it's not a solution to yarn link.
but a solution to anyone who have problem with managing local repos with yarn
and npm
simply use yalc
to manage your local packages instead of yarn link
or yarn add link:...
Upvotes: 5
Reputation: 111
We will need styled-component library in devDependencies of core repo, as it is required to develop reusable components in core repo.
At the same time we will need to tell app repo to load peerDependencies of core repo from node_modules of app repo.
We can use webpack for that, For example if we have used react-scripts to generate app repo, we can run yarn eject and locate webpack.config.js in config folder and can change resolve.alias section.
app/config/webpack.config.js
{
...
resolve: {
...
alias: {
...
core: path.resolve("./node_modules/core") // path must be imported above.
}
}
}
For more details : https://blog.maximeheckel.com/posts/duplicate-dependencies-npm-link
Upvotes: 1
Reputation: 23586
As you said, typescript is resolving these 'incorrectly'.
To overcome this, tell typescript to resolve the problematic packages in the consumer's node_modules
in tsconfig.json > compilerOptions > paths
like so:
"paths": {
"rxjs/*": ["node_modules/rxjs/*"],
}
Also, see this post for more.
Upvotes: 0