How can I `npm link` a typescript dependency with peer dependencies?
npm, reactjs, typescript
Solution
This problem isn't particularly related to typescript, but is a general problem of how to link two javascript packages together and prevent libraries from loading multiple times. A big factor on how you solve this is based on what build/bundler you use. I think this stackoverflow answer is pretty good if you only care about de-duping react.
Here is an example of solving it using webpack.
The first thing is make sure any shared dependencies in your child package are devDependencies and peerDependencies and your parent package is setting them as the needed dependencies and devDependencies.
A - package.json
{
"dependencies": {
"B": "1.0.0",
"react": "x.x.x",
},
"devDependencies": {
"@types/react": "x.x.x"
}
}
B - package.json
{
"version": "1.0.0",
"peerDependencies": {
"@types/react": "x.x.x",
"react": "x.x.x"
},
"devDependencies": {
"@types/react": "x.x.x",
"react": "x.x.x"
}
}
If you are running webpack from package A, you need to make sure to resolve node_modules when applicable only from package A's node_modules.
const path = require('path')
module.exports = {
// rest of your webpack condig...
resolve: {
modules: [path.resolve(__dirname, 'node_modules'), 'node_modules']
}
}
Here is also another solution using react-app-rewired that does the same thing
const path = require('path')
module.exports = function override(config) {
config.resolve = Object.assign({}, config.resolve, {
modules: [path.resolve(__dirname, 'node_modules'), ...config.resolve.modules]
})
return config
}
Problem
I have a React/Redux typescript project A. My team decided to split out some of the React components and Redux code into an NPM module, so I created another React/Redux TS project B. Initially, when I tried to install B from A, I got errors due to type redeclarations, since both A and B depend on the same type declarations files (react, redux, etc). So I moved all of B's @types dependencies to be peer dependencies. This allows me to properly install B from A. However, for development purposes, I would like to `npm link` to B from A, so I don't constantly have to recompile and reinstall B. But because `npm link` creates a symlink, it points to the entire B project, including the type definitions that I need to avoid. Does anyone know how to solve this conundrum?