Simone Pontiggia
Simone Pontiggia

Reputation: 204

Npm - how to manage one-repo, multi-package codebase

I’m building a node.js app that needs to be scalable and maintainable. The idea is to have one repository, but with more than one module inside it.

We are using local modules with npm, but we have a problem is that when we update a modules npm won’t update the dependent services.

here an example of the package.json

// ./app/package.json
{
   "dependencies": {
     "error-lib": "file:../modules/error-lib"
   },
   "scripts": {
     "start": "node app.js",
     "debug": "node --inspect-brk app.js",
   },
   "main": "app.js",
}

// ../modules/error-lib/pacjake.json
{
  "name": "error-lib",
  "version": "1.0.0",
  "main": "index.ts"
}

I have one problem when a developer updates the error-lib module, an npm install command won't update the old error-lib inside app/node_modules.

I don't want to bump the version of the modules on every change because they follow the same versioning and release lifecycle. And I don't want to rm -rf modules manually every time.

Any idea on how to automate a repo with many local modules?


TL;DR (Why one repo, many local modules)

We came from a Java background, where we have a single repo multi-module architecture managed by maven. What we do in maven is to isolate services, common-library, data model in isolated modules.

We have only one repo for all the modules and service since everyone follows the same release cycle with a uniform versioning.

When a developer needs to apply some change he or she can update one of the modules or the services and maven will take care of every dependency and the code will be up to date and ready to rock.

But we want separate modules for many reasons:

  1. This will force us to decouple the functionality and make code reusable since every module can virtually be placed in a separate repo at any time.
  2. If some module will become usable outside of the repo can be externalized and maintained.

We want to achieve the same design for a new part in node.js

Upvotes: 2

Views: 4879

Answers (1)

JJWesterkamp
JJWesterkamp

Reputation: 7916

Looks like you need $ npm link instead, creating symlinks to your packages within ./app/node_modules. This way, the linked packages are always 'up-to-date'.

Linking a package is a 2-step process:

  1. $ npm link at ../modules/error-lib creates a symbolic package in your global node_modules folder under the name error-lib, specified in ../modules/error-lib/package.json its "name" value.

  2. $ npm link error-lib at ./app to create the second link inside ./app/node_modules to <global-node_modules>/error-lib.

more about npm link


Edit in response to your comment:

I've seen some drawbacks of npm link:

  1. the dependency is not listed in the app package.json, so how I know which dependency I'm linking?

  2. the node_modules is not committed on the repo, so the CI/CD will need to do the linking while listing modules/error-lib inside the app package.json I have a place to take track of the dependencies.

There is any best practice on how to automate npm link or to mitigate the drawbacks?

NPM packages are supposed to be distributed through the npm registry. This means that your error-lib package also should be distributed this way, and be installed as any other package. This will require you to list your package in the package.json file in advance, which is essentially what you want.

If you instead intend to keep everything in one place there is no use in using NPM at all. Just resolve your packages with relative import paths in your software.

Since you said that all the packages follow the same release cycle as your main software, and they live in the same repo, why would you resolve these packages with NPM while they seem more like just part of the software?

error-lib is either a package, or it is not. If it is, it ideally has its own CI/CD pipeline, as large or tiny as required, involving testing, building and distribution. This pipeline is then to be run before the pipeline of your dependent repositories.

Upvotes: 2

Related Questions