I'm developing a module A. The user can, optionally, inject a Winston logger to my module, therefore winston
is its peer dependency.
Whenever I install my module A in another module where I don't want to log stuff (therefore I don't include Winston) and try to tsc
it, Typescript yells:
Cannot find module 'winston' or its corresponding type declarations.
How do I go about it?
Optional dependencies are used when it's not possible (for whatever reason) to split a project into sub-modules. The idea is that some of the dependencies are only used for certain features in the project and will not be needed if that feature isn't used.
Peer dependencies are a special type of dependency that would only ever come up if you were publishing your own package. Having a peer dependency means that your package needs a dependency that is the same exact dependency as the person installing your package.
Finally, optionalDependencies are dependencies that don't necessarily need to be installed. If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the optionalDependencies object.
Peer Dependencies are used to specify that our package is compatible with a specific version of an npm package. Good examples are Angular and React. To add a Peer Dependency you actually need to manually modify your package.json file.
Since NPM v7.x, you can use the peerDependenciesMeta
package.json config, which allows exactly that option.
For example, in your "Module A" package.json
:
"peerDependencies": {
"winston": "> 1.0.0 <= 1.2.10",
"foo": "~2.3.0"
},
"peerDependenciesMeta": {
"winston": {
"optional": true
}
}
In this case, when installing Module A as a dependency of another project, it will allow installing winston
dependency version in the semver range specified > 1.0.0 <= 1.2.10
, but if it's not present at all, you won't get errors, so it will be allowed as well.
Note that following this example, foo
dependency would be still required because it's not marked as optional
.
Extra tip: you can check and test ranges on available NPM packages using this utility https://semver.npmjs.com/, it helped me as well.
PS. this is my first answer on SO! :)
Just a small addition to @tmilar's answer.
I'm using the same way to add optional dependancy (and also winston :))
the example is for npm@7 which supports peerDependenciesMeta
"peerDependencies": {
"winston": "~3.3.0"
},
"peerDependenciesMeta": {
"winston": {
"optional": true
}
}
for optional dependencies you should expect exceptions on require and check package versions
let winston;
let winstonVersion;
try {
winston = require('winston')
winstonVersion = require('winston/package.json').version
} catch (er) {
winston = null
}
if (isUnsupportedVersion(winstonVersion) ) {
winston = null
}
// .. then later in your program ..
if (winston) {
winston.doSomething()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With