Search code examples
node.jsnpmmonorepopeer-dependencies

Using Peer Dependencies With Local (file:../some-lib) Dependencies


I have a monorepo that has many micro-services in it. There are some library-type functions / classes that I want to make available to any micro-service that needs it. However, if that library package declares a peer dependency, the peer dependency is not found when running code from within the thing that depends on the library.

Consider this repo structure:

  • lib
    • some-library (peerDepends on foo)
      • index.js (requires foo)
      • node_modules will be empty
  • services
    • some-service (depends on foo, and some-library)
      • index.js (requires some-library)
      • node_modules will have:
      • foo
      • some-library will be a symlink to ../../lib/some-library

When running node services/some-service/index.js, you'll get the error "Cannot find module 'foo'", emanating from lib/some-library/index.js.

Presumably this happens because node is only looking at lib/some-library/node_modules and any node_modules folder that is in an ancestor directory. But since this code was run from services/some-service (as the working directory), and because of the symlink in services/some-service/node_modules, I would've expected this to work.

Here's a repo you can easily clone to see the problem: https://github.com/jthomerson/example-local-dependency-problem

git clone git@github.com:jthomerson/example-local-dependency-problem.git    
cd example-local-dependency-problem    
cd services/some-service    
npm install    
node index.js    

I only see two solutions:

  • Don't use peerDependencies inside the library
  • Install each peer dependency at the root of the project for the sake of local development and testing.

Neither of those is a real great solution because it doesn't allow each service to have different versions of the dependencies, and thus means that if the local version (or the library's version) of a dependency is bumped, all services that uses the library then have their dependencies version bumped at the same time, which makes them more brittle because they're all tied together.


Solution

  • How about adding the --preserve-symlinks flag? E.g.:

    node --preserve-symlinks index.js 
    

    Here's a link to the docs