lerna

Lerna is a management tool that optimizes the workflow of a multi-package code base hosted on Git/NPM. It allows you to manage multiple sub-projects under the main project, eliminating the dependency of multiple packages and the need to manually maintain multiple packages at release time.

To solve the scene

Json {"name": "module-1", "version": "1.0.0", "dependencies": {"module-2": "^" 1.0.1}} / / module - 2 package. Json {" name ":" the module - 2 ", "version" : "1.0.1," "dependencies" : {}}Copy the code

As shown above, module-1 depends on module-2. After module-2 is modified, you need to perform the following operations:

  1. Change the version number of Module-2 and release it.
  2. Change the dependency relationship of module-1, change the version number of module-1, and publish it.

How to use LerNA

The installation

yarn global add lerna
Copy the code

Initialize the file structure

// File structure --packages --module-1 package.json --module-2 package.json --lerna.json --package.jsonCopy the code

lerna.json

{" version ":" 1.0.0 ", "npmClient" : "yarn" and "command" : {" publish ": {" ignoreChanges" : ["ignored-file", "*.md"] }, "version": { "conventionalCommits": true } }, "packages": [ "packages/*" ], "ignoreChanges": [ "**/*.md" ] }Copy the code
  • Version: indicates the current repository version. Independent mode is enabled when independent is set to independent
  • NpmClient: the client that executes the command. The default value is NPM, which can be set to YARN
  • Command: indicates the command preset
    • Bootstrap: Presets the bootstrap command. Hoist to true promotes all module dependencies to the root directory.
    • Command. The publish. IgnoreChanges: Settings will not include lerna change/publish operation file path, use it to avoid some of the important changes of version update, such as updating the README. Spelling errors in md.
    • Version: Set lerna Version (including publish process).
      • ConventionalCommits: Generates CHANGELOG
  • Packages: The file path used to locate the package
  • UseWorkspaces: Unified YARN commands are executed in all project paths matched by workspaces, including tests, installation dependencies, and execution scripts. The default is false. Dependency packages are promoted to the root directory, and subpackages are promoted to the root directory to the module.
  • IgnoreChanges: Ignores changes to certain files.

Working mode

Fixed/Locked mode (default)

When publish, “version”: “0.1.5” will be added to lerna.json file according to this number. Select this number only once.

Independent mode

Each time you publish, you will get a prompt for each package that has changed to specify whether it is a patch, minor, major, or custom change.

The command

Create or adapt as lerNA project

lerna init
Copy the code

Creating a package

Lerna create package-a // Create a b and place it under package-b (package-b needs to be specified in workspaces of the root directory first)Copy the code

Add all dependencies in the package

lerna add dep-name // Adds the module-1 package to the packages in the 'prefix-' prefixed folders lerna add module-1 packages/prefix-* // Install module-1 to module-2 lerna add module-1 --scope=module-2 // Install module-1 to module-2 in  devDependencies lerna add module-1 --scope=module-2 --dev // Install module-1 in all modules except module-1 lerna add module-1 // Install babel-core in all modules lerna add babel-coreCopy the code

List all packages

lerna list
Copy the code

Import a package that already exists locally

lerna import /xxx/xxx/xx
Copy the code

Remove all dependencies from packages

lerna exec -- yarn remove dep-name
Copy the code

Add dependencies to the specified package

lerna add dep-name --scope module-a
Copy the code

Removes dependencies from the specified package

Lerna does not have such a command as remove at present. You need to delete the corresponding dependencies in package.json of the corresponding package, and then execute lerna bootstrap.

Introduce package-b in package-a

lerna add package-a --scope package-b
Copy the code

Execute all the script commands in the package

Lerna run test --streamCopy the code

Run arbitrary commands in each package

lerna exec -- < command > [..args] # runs the command in all packages
lerna exec -- rm -rf ./node_modules
lerna exec -- protractor conf.js
lerna exec --scope my-component -- ls -la
Copy the code

Execute the script command in the specified package

lerna exec --scope package-a -- yarn run dev
Copy the code

The project package establishes a soft chain

lerna link
Copy the code

Delete the node_modules directory for all packages

lerna clean
Copy the code

List the packages that lerna publishes to update next release

lerna changed
Copy the code
  1. Git add and git commit
  2. Git diff –name-only v

release

Release a new version of the updated package; Use the new version number tag; Upgrade all libraries in NPM and Git

lerna publish [--npm-tag [tagname], --canary/-c, --skip-git, --force-publish [packages]] lerna publish --pre-dist-tag alpha prerelease Lerna publish --force-publish --pre-dist-tag Latest patchCopy the code

If the package name has scope, such as name: @vue/cli, you need to specify it under package.json of the package:

 "publishConfig": {
    "access": "public"
  }
Copy the code

Lerna publish:

  1. Call lerna version
  • Find the packages that have changed since the last release
  • Prompts developers to determine the release number
  • Update the version field of package.json in all updated packages
  • Update the dependency version numbers in packages that depend on the updated package
  • Update the version field in lerna.json
  • Commit the above changes with a tag
  • Push to git repository
  1. Use NPM publish to push the new version to NPM

Setting the specified version

# # lerna version 1.0.1 clear lerna version patch semver keyword lerna version # from tip lerna version [major | minor | patch | Premajor | preminor | prepatch | prerelease] # using the next version of semantic value, it will skip the "as..." A prompt to select a new versionCopy the code

Other instructions

  • Lerna Bootstrap [–independent/ -I]: Lerna bootstrap, install+ module soft chain
  • Lerna import: Imports packages from the local path into packages/ and commits action records

Other supporting dependencies

  • Commitizen: Formats the submission format.
  • Cz-lerna-changelog: Submission specification customized by LERNA. Package adds the following configuration:
{ "name": "root", "private": true, "scripts": { "c": "git-cz" }, "config": { "commitizen": { "path": "./node_modules/cz-lerna-changelog"}}, "devDependencies": {"commitizen": "^3.1.1", "cz-lerna-changelog": "^2.0.2", "lerna": "^3.15.0"}Copy the code
  • Husky: Intercepts custom hook scripts that inherit Git hooks

Some conventions

For projects with Monorepo structure, it is better to keep the structure of each package uniform

  • The package entry is uniformly index.js
  • The source code entry of each package is SRC /index.js
  • The compilation entry of each package is dist/index.js
  • All packages use ES6 syntax, compile, compress and output to DIST using Babel
  • When each package is released, only dist directory is released, not SRC directory
  • The LOCAL_DEBUG environment variable is injected into each package, and the debug environment ruquire(./ SRC /index.js) ensures that all source code can be debugged. The distribution environment Ruquire (./dist/index.js) ensures that all source code is not distributed.

Refer to the article

  • lerna-github
  • Lerna best practices for managing front-end Packages
  • Monorepo project best practices based on Lerna management Packages