Gadi
Gadi

Reputation: 482

Node.JS: Working with multiple Git repositories

We have a node.js project with a few modules which spans across multiple Git repositories. The modules have dependencies between them.

For example:

common module resides in its own repository. execution module resides in a separate repository, and has a (npm) dependency on common.

So, the directory structure in execution includes (once npm install is executed) common under node_modules.

Our problem is, when developers are working on execution, they some times need to modify common as well. In order to 'see' their changes, they have one of two options we currently use: Either modify node_modules/common (which is ugly, untracked, etc.), or modify the common repository, then push+npm install their changes (which, while cleaner, is quite cumbersome).

What we're wondering is if there's a better alternative for this work process...

Upvotes: 5

Views: 2987

Answers (3)

Ryan Saunders
Ryan Saunders

Reputation: 519

Problems with npm link

npm link generally works quite well, but there's a few issues with it when you have a more complex linking of several packages:

  1. It's slow.
  2. It's difficult to unlink things when you're done testing locally. You could run npm unlink or npm unlink <package-name> but that will remove it from package.json. npm i also does not remove the link.
  3. It doesn't work if you have more than one level of dependencies you want linked, especially when there are complex relationships with the dependencies such as:
- root:
-- dependencyC
-- dependencyA [linked]:
--- dependencyB
-- dependencyB [linked]:
--- dependencyC

As dependencyC will be a different reference within root and dependencyB. You'd have to link all such dependencies locally for it to work. Not so much an issue with functional programming, but for OO classes/prototypes, it will say the reference does not match.

Solution

While looking for a solution to this problem with our own development, I came across https://github.com/coopcycle/coopcycle-js/issues/4 which mentions to simply use ln -sf <link> instead of npm link as ln creates a symlink for you. It's fast (instantaneous), easy to comprehend, and easy to undo (just run npm i).

Given the same example above (wanting to link dependencyA and dependencyB to root) you would run:

In root:

/root % npm i
/root % cd node_modules
/root % rm -rf dependencyA
/root % rm -rf dependencyB
/root % ln -sf ../../../dependencyA
/root % ln -sf ../../../dependencyB

Assuming ../../../dependencyA is the relative path to dependencyA.

In dependencyA:

/root % npm i
/root % cd node_modules
/root % rm -rf dependencyB
/root % ln -sf ../../../root/node_modules/dependencyB

In dependencyB:

/root % npm i
/root % cd node_modules
/root % rm -rf dependencyC
/root % ln -sf ../../../root/node_modules/dependencyC

Upvotes: 0

Rotem Harel
Rotem Harel

Reputation: 736

You could avoid modifying your package.json file by using the npm link command. This will automatically configure the execution package to symlink its node_modules/common directory to your local clone of common.

How to use this method

  1. Inside your common directory type: npm link. This will create a global reference to your common folder in npm, identified by common (assuming common is the exact name of your node package).
  2. Inside your execution directory type: npm link common. This will symlink the node_modules/common folder into your local copy of the common directory.

When you're done making changes to your common folder, you need to update that package online, and then change the package.json of execution to point to the updated version of common.

I prefer this method over the one suggesting to point package.json to your local repository, because that leaves your package.json in an invalid state that you might accidentally commit and push.

Upvotes: 7

Vishwanath
Vishwanath

Reputation: 6004

I assume you are using them as a dependency using package.json, which allows you to require them with the name and not the path. (You also have goodies of the version handling with this.) . I couldnt find any option to remove the step of npm install but I did found something which can remove the step of git push and will make your npm install faster.

Local dependencies.
Using local paths as dependencies which can be your some other git repo, you can make changes directly to the git repo of your dependency. This allows you to change the code and test it without pushing. (Although you have to do npm install again in the main module, which will duplicate the working copy of your dependency in your node modules).

Word of caution : You have to take care that you push the final changes made to your dependency code once you have finished working on both, otherwise other developers might go in inconsistent state.

How to add local dependencies

 "dependencies" : {
       "here" : "file:./test/git/repo/here#0.0.1"
 }

Note that this local dependency feature was added to npm in version 2.0. So you might need to update your node if you dont already have npm 2.0+

Upvotes: 3

Related Questions