Working with dependencies
Here are some of the package management tasks that are periodically performed across the monorepo.
Note: The monorepo is using npm 8 “workspaces”, which simplify the dependency management across projects through the use of many top-level commands which target specific workspaces.
Adding new project dependencies
To install a new node module into a project, from the top-level of the repository, run:
$ npm --workspace <workspace_path> install [--save-dev] some-node-package-name@latest
workspace_path
is the folder containing the package.json you wish to update. For exampleservices/logging
.--save-dev
is optional, depending on whether the dep is a production dep or only used during development/build.- Make sure to specify a package version or
@latest
so the dependency doesn’t get installed with the*
wildcard.
Here’s a full example of installing the immer
package into the @carbon-platform/logging
package:
$ npm --workspace services/logging install immer@latest
Removing dependencies works the same way with the npm uninstall
command.
⚠️⚠️⚠️ Note ⚠️⚠️⚠️
It is important to only run install commands from the top-level of the repository. This allows a single
package-lock.json
file to be maintained at the root of the repo. If you see that you’ve accidentally created another lock file in your git views, don’t commit it! Delete it and re-run the install/update/uninstall commands from the top-level of the repo.
Updating node modules
To update the node modules across all workspaces, from the top-level in the repo, run the following commands.
npm update --save
CI=true npm install && npm install
Note: Running npm install twice during this helps to eliminate wildcard versions from showing up in the package-lock.json file.
Major version upgrades
Since package.json
versions are pinned such that they don’t jump major versions during an npm update
, npm-check-updates
(ncu
) can be used instead. To update major versions via ncu
, run the following commands. Be sure to answer “no” each time it asks if you want to run an npm install
.
npx --workspaces --include-workspace-root ncu --upgrade --interactive --target=latest
CI=true npm install && npm install
Note: An ncu target of
latest
orpatch
can also be used, depending on the objective.
Note: Avoid picking up “rc” releases of Carbon packages, if possible.
To update the node modules only for a specific workspace, from the top-level in the repo, run:
$ npm --workspace <workspace_path> update --save
Things to check/run after updating node modules
- Run the project-wide linter/formatter (
lint
) - Run project-wide unit tests (
test
) - Build all packages and services (
all:build
) - Spot check of the web-app running locally
- (Optional) Docker builds of the services
Info about the “root” workspace
When a node module is used in more than one workspace, it’s often a good idea to move it to the root
workspace if it should be considered as a core module for all workspaces.
An example of this is the version of TypeScript that is used across the monorepo. Individual workspaces do not install TypeScript directly. They get it implicitly from the root
workspace. When the root
workspace version of TypeScript is updated, so too are the workspaces which depend on it. This is true for any module installed in the root
workspace.
Individual workspaces can override the root
workspace version of a dependency by explicitly installng it in their package.json, but this is not advisable because it circumvents the root
workspace as the authoritative source for these core (common) packages.
Since the root
workspace contains dependencies that are used across multiple other workspaces in the repo, these dependencies should only appear in the top-level node_modules
folder and not in the node_modules
folders of individual packages/services/workspaces. Dependencies in individual workspace node_modules
folders should only be present if the workspace requires a specific version of a dependency which diverges from the “common” one available in the top-level node_modules
folder.
It’s a good idea to periodically check all of these folders to make sure what’s in there is expected.
Rebuilding the lockfile
From time to time, the sequence of dependency installations may result in undesirable results in the package-lock.json file or individual node_modules
folders. To remedy this and rebuild the lockfile, do the following:
rm package-lock.json
rm -rf node_modules
find . -name node_modules | xargs rm -rf
CI=true npm install && npm install
Note: this will result in updates to the node modules across the project (if any are available).