or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-lerna--link

Symlink together all packages that are dependencies of each other in Lerna monorepos

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@lerna/link@6.6.x

To install, run

npx @tessl/cli install tessl/npm-lerna--link@6.6.0

index.mddocs/

@lerna/link

@lerna/link is a Lerna command package that creates symbolic links between packages that depend on each other within a Lerna monorepo. It enables local development workflows where changes in one package are immediately reflected in dependent packages without requiring package republishing or manual linking.

Package Information

  • Package Name: @lerna/link
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @lerna/link or available via lerna CLI
  • Engine Requirements: Node.js ^14.17.0 || >=16.0.0

Core Imports

// CommonJS style (Node.js require)
const linkCommand = require("@lerna/link");
const { LinkCommand } = require("@lerna/link");
const command = require("@lerna/link/command");
// TypeScript style (using CommonJS imports)
import linkCommand = require("@lerna/link");
import { LinkCommand } = require("@lerna/link");
import command = require("@lerna/link/command");

Basic Usage

Command Line Interface

# Link all interdependent packages
lerna link

# Force linking regardless of version ranges
lerna link --force-local

# Use specific subdirectory as symlink source
lerna link --contents dist

# Convert existing links to file: specifiers
lerna link convert

Programmatic Usage

const linkCommand = require("@lerna/link");

// Create command instance
const command = linkCommand(process.argv);

// Initialize and execute
await command.initialize();
await command.execute();

Architecture

@lerna/link is built around several key components:

  • Factory Pattern: The main export is a factory function that creates LinkCommand instances, allowing for dependency injection and testing flexibility
  • Command Class Structure: Extends Lerna's base Command class, integrating with the Lerna command system and lifecycle management
  • Package Graph Analysis: Uses PackageGraph to analyze dependencies between packages and determine which packages need linking
  • Symbolic Link Management: Creates and manages symbolic links in node_modules directories and .bin directories for executables
  • Package Manager Integration: Validates npm client compatibility and throws errors for unsupported package managers like pnpm
  • File Specification Conversion: Provides capability to convert symbolic links to relative file: specifications in package.json files

The command operates in two main modes: standard linking (creating symbolic links) and conversion mode (updating package.json files with file: specifications).

Capabilities

Factory Function

Creates a new LinkCommand instance with provided command-line arguments.

function factory(argv: NodeJS.Process["argv"]): LinkCommand;

LinkCommand Class

Main command class that handles package linking operations. Extends Lerna's base Command class.

class LinkCommand extends Command<LinkCommandOptions> {
  allPackages: Package[];
  targetGraph?: PackageGraph;
  
  get requiresGit(): boolean;
  initialize(): void;
  execute(): Promise<any>;
  convertLinksToFileSpecs(): Promise<any>;
}

Properties

  • allPackages: Array of all packages in the monorepo
  • targetGraph: Graph of package dependencies for linking operations

Methods

  • requiresGit: Returns false, indicating git is not required for this command
  • initialize(): Sets up the command, validates npm client, and builds package graph
  • execute(): Performs the linking operation or converts links to file specifications
  • convertLinksToFileSpecs(): Converts symbolic links to relative file: specifications in package.json files

Command Module

Yargs command module configuration for CLI integration. Provides the CLI interface and option definitions.

interface CommandModule {
  command: string;
  describe: string;
  builder: (yargs: any) => any;
  handler: (argv: any) => any;
}

The command module exports:

  • command: "link"
  • describe: "Symlink together all packages that are dependencies of each other"
  • builder: Configures command options including --force-local, --contents, and the convert subcommand
  • handler: Delegates to the factory function to create and execute the LinkCommand instance

The builder function also registers the convert subcommand with the description "Replace local sibling version ranges with relative file: specifiers".

Command Options

Options interface extending Lerna's base CommandConfigOptions.

interface LinkCommandOptions extends CommandConfigOptions {
  contents: string;
  forceLocal: boolean;
}

Option Properties

  • contents: Subdirectory to use as the source of the symlink (default: current directory)
  • forceLocal: Force local sibling links regardless of version range match

Command Line Options

--force-local

Forces creation of symbolic links for local dependencies regardless of whether their version ranges match.

lerna link --force-local

--contents

Specifies a subdirectory to use as the source of the symlink, applying to all packages.

lerna link --contents dist

convert subcommand

Replaces local sibling version ranges with relative file: specifiers in package.json files.

lerna link convert

Types

LinkCommandOptions

interface LinkCommandOptions extends CommandConfigOptions {
  contents: string;
  forceLocal: boolean;
}

Dependencies

The package relies on several core Lerna types and utilities:

// From @lerna/core
class Command<T extends CommandConfigOptions>;
interface CommandConfigOptions;
class Package;
class PackageGraph;
class PackageGraphNode;
function symlinkDependencies(
  packages: Package[],
  packageGraph: PackageGraph | undefined,
  tracker: any
): Promise<any>;
class ValidationError;

Error Handling

PNPM Workspace Validation

The command throws a ValidationError when attempting to use with pnpm workspaces:

class ValidationError extends Error {
  constructor(code: string, message: string);
}

Specific error thrown:

  • Code: "EWORKSPACES"
  • Message: "Link is not supported with pnpm workspaces, since pnpm will automatically link dependencies during pnpm install. See the pnpm docs for details: https://pnpm.io/workspaces"

This error is thrown during the initialize() method when this.options.npmClient === "pnpm".

Behavior

Package Discovery

The command analyzes all packages in the Lerna monorepo and identifies dependencies between them. It creates symbolic links only for packages that are listed as dependencies of other packages in the same monorepo.

Symlink Creation

  • Links package directories to node_modules folders of dependent packages
  • Links executable files to .bin directories for CLI commands
  • Supports custom source directories via publishConfig.directory in package.json
  • Respects version range matching unless --force-local is used

Version Range Handling

By default, symbolic links are only created when the dependency version range matches the local package version. The --force-local flag bypasses this check and creates links regardless of version compatibility.

File Specification Conversion

The convert subcommand transforms the monorepo to use file: dependencies instead of symbolic links, making packages reference each other through relative file paths in their package.json files.

Integration

Lerna Command System

@lerna/link integrates with Lerna's command system and can be invoked through:

  • Direct package usage: require("@lerna/link")
  • Lerna CLI: lerna link
  • Programmatic Lerna API

Package Manager Compatibility

  • Supported: npm, yarn
  • Not Supported: pnpm (throws validation error due to pnpm's automatic workspace linking)

Build Integration

Works with packages that use publishConfig.directory to specify build output directories, linking the built artifacts instead of source code.