Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm. It allows you to manage your project's dependencies, versioning, and publishing in a more organized manner, especially when dealing with a monorepo containing multiple packages.
Bootstrap
Installs all of the dependencies for each package, links any cross-dependencies, and ensures that each package can find and use the correct versions of each other.
lerna bootstrap
Publish
Helps with versioning of the changes and publishing packages that have been updated to npm. It can automatically determine version bumps based on conventional commits, create git tags, and push releases to the repository.
lerna publish
Run
Runs an npm script in each package that contains that script. The '--scope' flag can be used to run the script only in specified packages.
lerna run --scope my-package test
Exec
Executes an arbitrary command in each of your packages. In this example, it removes the 'node_modules' directory from each package.
lerna exec -- rm -rf ./node_modules
List
Lists all of the public packages in the current Lerna repo.
lerna list
Changed
Lists public packages that have changed since the last tagged release.
lerna changed
Diff
Shows the diff since the last release for a single package or all packages.
lerna diff
Import
Imports an external repository into the 'packages' folder of your Lerna monorepo, preserving the commit history.
lerna import <path-to-external-repository>
Nx is a suite of powerful, extensible dev tools that help you develop, test, build, and scale Angular and React applications with fully integrated support for monorepo management. It provides a more integrated experience for building applications compared to Lerna, which is more focused on package management.
A tool for managing JavaScript projects with multiple packages.
While developing Babel I followed a monorepo approach where the entire project was split into individual packages but everything lived in the same repo. This was great. It allowed super easy modularisation which meant the core was easier to approach and meant others could use the useful parts of Babel in their own projects.
This tool was abstracted out of that and deals with bootstrapping packages by linking them together as well as publishing them to npm. You can see the Babel repo for an example of a large Lerna project.
Splitting up large codebases into separate independently versioned packages is extremely useful for code sharing. However, making changes across many repositories is messy and difficult to track, and testing across repositories gets complicated really fast.
To solve these (and many other) problems, some projects will organize their codebases into multi-package repostories (sometimes called monorepos). Projects like Babel, React, Angular, Ember, Meteor, Jest, and many others develop all of their packages within a single repository.
Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.
There's actually very little to it. You have a file system that looks like this:
my-repo/
package.json
packages/
package-1/
package.json
package-2/
package.json
The two primary commands in Lerna are lerna bootstrap
and lerna publish
.
bootstrap
will link dependencies in the monorepo together.
publish
will help publish updated packages.
The instructions below are for Lerna 2.x which is currently in beta and actively being worked on. We recommend using it instead of 1.x for a new lerna project. Check the wiki if you need to see the 1.x README.
Let's start by installing Lerna globally with npm.
$ npm install --global lerna
# install the latest 2.x version
$ npm install --global lerna@2.0.0-beta.13
Next we'll create a new git repository:
$ git init lerna-repo
$ cd lerna-repo
And now let's turn it into a Lerna repo:
$ lerna init
Your repository should now look like this:
lerna-repo/
packages/
package.json
lerna.json
This will create a lerna.json
configuration file as well as a packages
folder.
Note: Depending on the project you might want to run this in
--independent
mode (each package is separately versioned), also described in more detail below.
Lerna projects operate on a single version line. The version is kept in the lerna.json
file at the root of your project under the version
key. When you run lerna publish
, if a module has been updated since the last time a release was made, it will be updated to the new version you're releasing. This means that you only publish a new version of a package when you need to.
$ lerna init
Create a new lerna repo or upgrade an existing repo to the current version of Lerna.
Lerna assumes you have already created a git repo with
git init
.
devDependency
in package.json
if it isn't already there.lerna.json
config file to store the version
number.packages
folder if it's not created already.Example output on a new git repo:
> lerna init
$ Lerna v2.0.0-beta.9
$ Creating packages folder.
$ Updating package.json.
$ Creating lerna.json.
$ Successfully created Lerna files
Options
--independent
/-i
– Use independent versioning mode.$ lerna bootstrap
Bootstrap (setup) the packages in the current Lerna repo. Installs all their dependencies and links any cross-dependencies.
packages
that depend on each other (This doesn't use npm link).npm install
all outside dependencies of each package.Currently, what lerna does to link internal dependencies is replace the
node_modules/package1
with a link to the actual file in the repo.
bootstrap
worksWe'll use babel
as an example.
babel-core
has a dependency on babel-generator
and say source-map
(among others).babel-core
's package.json
, it has them as keys in dependencies
.// babel-core package.json
{
"name": "babel-core",
...
"dependencies": {
...
"babel-generator": "^6.9.0",
...
"source-map": "^0.5.0"
}
}
babel-generator
is while sourcemap
is not.sourcemap
is npm install
ed like normalbabel-core/node_modules/babel-generator
is replaced with 2 files
package.json
with keys name
and version
index.js
with the contents module.exports = require("relative-path-to-babel-generator-in-the-lerna-repo")
babel-generator
in node_modules
with the actual babel-generator
files.$ lerna publish
Create a new release of the packages that have been updated. Prompts for a new version and updates all the packages on git and npm.
packages
that has been updated since the last version to npm with the dist-tag lerna-temp
.lerna updated
to determine which packages need to be published.version
key in lerna.json
.package.json
of all updated packages to their new versions.lerna-temp
tags and add the tags to latest
.A temporary dist-tag is initally used to prevent the case where only some of the packages are published due to an error.
$ lerna publish --npm-tag=next
Publish to npm with the given npm dist-tag (Defaults to latest
).
This option could be used to publish a prerelease or beta version.
The
latest
tag is the one that is used when a user doesnpm install package
.
$ lerna publish --canary
The canary
flag will publish packages after every successful merge using the sha as part of the tag.
It will take the current version
and append the sha as the new version
. ex: 1.0.0-canary.81e3b443
.
More specifically, canary
flag will append the current git sha to the current version
and publish it.
The use case for this is a per commit level release or a nightly release.
$ lerna publish --skip-git
Don't run any git commands.
Only publish to npm; skip commiting, tagging, and pushing git changes (this only affects publish).
$ lerna publish --force-publish=package-2,package-4
# force publish all packages
$ lerna publish --force-publish=*
Force publish for the specified packages (comma-separated) or all packages using *
(skips the git diff check for changed packages).
$ lerna updated
Check which packages
have changed since the last release (the last git tag).
Lerna determines the last git tag created and runs something like git diff --name-only v6.8.1
to get all files changed since that tag.
$ lerna diff [package?]
$ lerna diff
# diff a specific package
$ lerna diff package-name
Diff all packages or a single package since the last release.
Similar to
lerna updated
. This command runsgit diff
.
$ lerna ls
List all of the public packages in the current Lerna repo.
$ lerna run [script] // runs npm run my-script in all packages that have it
$ lerna run test
$ lerna run build
Run an npm script in each package that contains that script.
Lerna will log to a lerna-debug.log
file (same as npm-debug.log
) when lerna encounters an error running a command.
Lerna also has support for scoped packages.
Running lerna
without arguments will show all commands/options.
{
"lerna": "2.0.0-beta.9",
"version": "1.1.3",
"publishConfig": {
"ignore": [
"ignored-file",
"*.md"
]
}
}
lerna
: the current version of lerna
being used.version
: the current version of the repository.publishConfig.ignore
: an array of globs that won't be included in lerna updated/publish
. Use this to prevent publishing a new version just because of README.md
typo.FAQs
Lerna is a fast, modern build system for managing and publishing multiple JavaScript/TypeScript packages from the same repository
The npm package lerna receives a total of 764,559 weekly downloads. As such, lerna popularity was classified as popular.
We found that lerna demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.