Is there a way to specify different paths for the same dependencies in package.json?

Viewed 614

I am working on an npm package that includes an example directory to run/test the actual package. In the example directory, I have included back the parent package using "file:..".

This works fine when developing and making frequent changes to the parent package, but if I want to use the example as a stand-alone app, I would need to point to the actual npm package.

Is there a way to have "2 configs" in the same package.json:

  • one that points to `"file:.." for local development
  • one that points to the npm package to use as a stand-alone app

This would avoid duplicating the example directory

2 Answers

You could do this with lerna which is a mono-repository CLI tool.

First of all, you would have to define multiple projects within the same repository. Lerna calls these projects "packages" and stores all of them within a /packages folder.

package.json
/packages 
  /my1stPackage
      package.json
  /my2ndPackage   
      package.json

Lerna has all kind of optimizations, which I won't dive in too deep here. But there are a couple of basics:

  • to initially install all dependencies of all repos, run lerna bootstrap --hoist.
  • You can still run npm run ... as before, but those refer to your root package.json file. To run npm scripts for specific sub-package you should run lerna run <args> -scope=<packageName>. (e.g. lerna run build --scope=my1stPackage)

You can add shortcuts for this in the root /package.json script section.

"scripts": {
  "setup": "lerna bootstrap --hoist",
  "build:my1stPackage": "lerna run build --scope=my1stPackage"
}

What will interest you most, is that sibling packages can just reference each other from their specific package.json to include each other as dependencies.

So, let's assume that my1stPackage uses my2ndPackage. Inside the package.json file of my1stPackage there would be something like

"dependencies": {
  ...
  "my2ndPackage": "^0.0.1"
}

The my2ndPackage could actually be a package which is published in npm. However (!) while developing locally, lerna will add a symbolic link inside the /packages/my1stPackage/node_modules/my2ndPackage, which points to the folder of /packages/my2ndPackage. (And that really does work on all relevant operating systems.)

You package.json looks the same for local development as it does for people who download your package through npm. However, it's your lerna setup that fixes this with this symbol link.

I found two potential ways to do this:

But in my specific case, there are packages that can conflict between the parent and child (example) packages.

I couldn't find a robust way to make it work and decided that the simpler approach would be to simply create a separate repository that would contain a stand-alone version of the example directory and a script that can keep it up to date with the "master example" in the original repository. This way development stays fast and the "example copy" is easy to keep up to date without duplicating code.

Related