Skip to content

tsukiy0's blog

Manage a monorepo with Lerna

February 25, 2021

Lerna is a flexible tool for managing monorepos. It provides tools for installing, building, versioning and publishing multiple packages.

Even though Lerna is targed at monorepos, it can be used to manage a single package.

Configuring Lerna

  • lerna.json

    {” “}

    • Use fixed versioning so all packages move in lockstep
      • Consumers simply need to install the same version
      • Ensure to run lerna version with --force-publish so that all packages are upgraded regardless whether they have changed
      • independent versioning can be used when the packages in a monorepo do not import one another, i.e. are truly independent
    • Set npmClient to yarn to use the Yarn Workspaces backend which is noticeably faster when installing
  • package.json

    {” “}

    • Include the workspace block to use Yarn Workspaces

Installing

  • Installing

    yarn install
    • Yarn Workspaces will manage installing and deduping external packages
    • There should be a single node_modules and yarn.lock at the root of the monorepo
  • Install additional packages in the root

    yarn add rimraf --dev -W
    • -W indicates to install at the root package.json
  • Install additional packages

    lerna add rimraf --scope package-1
    • package-1 is the name of a package in the monorepo
    • The same command can be used to install one monorepo package in another monorepo package

Other scripts

  • Run scripts

    lerna run build
    • This will run the build script in any package that defines it in the package.json
    • The order that this script is run is determined by the package dependency on one another
      • e.g. if package-2 installed package-1, there is a dependency, thus scripts must first be run in package-1 before package-2

Publish workflow

Versioning and publishing are performed separately.

  • lerna version is run locally to bump all package versions, produce a changelog then tag and commit these changes.

    lerna version --force-publish --conventional-commits --conventional-prerelease -m \"chore: version\"
    • --conventional-commits will generate a CHANGELOG.md since the last version
    • --conventional-prerelease will create a prerelease version, e.g. 0.1.0.alpha.1
      • --conventional-graduate will create a stable release version, e.g. 0.1.0
    • A new commit with message defined by -m will be pushed
  • lerna publish is run on CI to publish versions that do not exist in the package repository (default NPM)

    lerna publish from-package --loglevel=verbose --no-verify-access --dist-tag prerelease --yes
    • --dist-tag determines the release channel

      • latest is the default channel used when someone install without specifying a version

        npm install package-1
        • Only publish to this channel when making an official stable release, i.e. after a lerna version --conventional-graduate
      • prerelease will only be installed if the version is specified explicitly or @prerelease is the version

        npm install package-1@prerelease
        • Useful for testing our own releases
        • Most understand that versions released can be subject to breaking API changes
    • --yes make this CI friendly by skipping interactive confirmation


tsukiy0