or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md
tile.json

index.mddocs/

0

# @lerna/link

1

2

@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.

3

4

## Package Information

5

6

- **Package Name**: @lerna/link

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @lerna/link` or available via `lerna` CLI

10

- **Engine Requirements**: Node.js ^14.17.0 || >=16.0.0

11

12

## Core Imports

13

14

```javascript

15

// CommonJS style (Node.js require)

16

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

17

const { LinkCommand } = require("@lerna/link");

18

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

19

```

20

21

```typescript

22

// TypeScript style (using CommonJS imports)

23

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

24

import { LinkCommand } = require("@lerna/link");

25

import command = require("@lerna/link/command");

26

```

27

28

## Basic Usage

29

30

### Command Line Interface

31

32

```bash

33

# Link all interdependent packages

34

lerna link

35

36

# Force linking regardless of version ranges

37

lerna link --force-local

38

39

# Use specific subdirectory as symlink source

40

lerna link --contents dist

41

42

# Convert existing links to file: specifiers

43

lerna link convert

44

```

45

46

### Programmatic Usage

47

48

```typescript

49

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

50

51

// Create command instance

52

const command = linkCommand(process.argv);

53

54

// Initialize and execute

55

await command.initialize();

56

await command.execute();

57

```

58

59

## Architecture

60

61

@lerna/link is built around several key components:

62

63

- **Factory Pattern**: The main export is a factory function that creates `LinkCommand` instances, allowing for dependency injection and testing flexibility

64

- **Command Class Structure**: Extends Lerna's base `Command` class, integrating with the Lerna command system and lifecycle management

65

- **Package Graph Analysis**: Uses `PackageGraph` to analyze dependencies between packages and determine which packages need linking

66

- **Symbolic Link Management**: Creates and manages symbolic links in `node_modules` directories and `.bin` directories for executables

67

- **Package Manager Integration**: Validates npm client compatibility and throws errors for unsupported package managers like pnpm

68

- **File Specification Conversion**: Provides capability to convert symbolic links to relative `file:` specifications in package.json files

69

70

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

71

72

## Capabilities

73

74

### Factory Function

75

76

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

77

78

```typescript { .api }

79

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

80

```

81

82

### LinkCommand Class

83

84

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

85

86

```typescript { .api }

87

class LinkCommand extends Command<LinkCommandOptions> {

88

allPackages: Package[];

89

targetGraph?: PackageGraph;

90

91

get requiresGit(): boolean;

92

initialize(): void;

93

execute(): Promise<any>;

94

convertLinksToFileSpecs(): Promise<any>;

95

}

96

```

97

98

#### Properties

99

100

- `allPackages`: Array of all packages in the monorepo

101

- `targetGraph`: Graph of package dependencies for linking operations

102

103

#### Methods

104

105

- `requiresGit`: Returns false, indicating git is not required for this command

106

- `initialize()`: Sets up the command, validates npm client, and builds package graph

107

- `execute()`: Performs the linking operation or converts links to file specifications

108

- `convertLinksToFileSpecs()`: Converts symbolic links to relative file: specifications in package.json files

109

110

### Command Module

111

112

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

113

114

```typescript { .api }

115

interface CommandModule {

116

command: string;

117

describe: string;

118

builder: (yargs: any) => any;

119

handler: (argv: any) => any;

120

}

121

```

122

123

The command module exports:

124

- **command**: "link"

125

- **describe**: "Symlink together all packages that are dependencies of each other"

126

- **builder**: Configures command options including `--force-local`, `--contents`, and the `convert` subcommand

127

- **handler**: Delegates to the factory function to create and execute the LinkCommand instance

128

129

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

130

131

### Command Options

132

133

Options interface extending Lerna's base CommandConfigOptions.

134

135

```typescript { .api }

136

interface LinkCommandOptions extends CommandConfigOptions {

137

contents: string;

138

forceLocal: boolean;

139

}

140

```

141

142

#### Option Properties

143

144

- `contents`: Subdirectory to use as the source of the symlink (default: current directory)

145

- `forceLocal`: Force local sibling links regardless of version range match

146

147

### Command Line Options

148

149

#### --force-local

150

151

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

152

153

```bash

154

lerna link --force-local

155

```

156

157

#### --contents

158

159

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

160

161

```bash

162

lerna link --contents dist

163

```

164

165

#### convert subcommand

166

167

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

168

169

```bash

170

lerna link convert

171

```

172

173

## Types

174

175

176

### LinkCommandOptions

177

178

```typescript { .api }

179

interface LinkCommandOptions extends CommandConfigOptions {

180

contents: string;

181

forceLocal: boolean;

182

}

183

```

184

185

### Dependencies

186

187

The package relies on several core Lerna types and utilities:

188

189

```typescript { .api }

190

// From @lerna/core

191

class Command<T extends CommandConfigOptions>;

192

interface CommandConfigOptions;

193

class Package;

194

class PackageGraph;

195

class PackageGraphNode;

196

function symlinkDependencies(

197

packages: Package[],

198

packageGraph: PackageGraph | undefined,

199

tracker: any

200

): Promise<any>;

201

class ValidationError;

202

```

203

204

## Error Handling

205

206

### PNPM Workspace Validation

207

208

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

209

210

```typescript { .api }

211

class ValidationError extends Error {

212

constructor(code: string, message: string);

213

}

214

```

215

216

Specific error thrown:

217

- **Code**: "EWORKSPACES"

218

- **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"

219

220

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

221

222

## Behavior

223

224

### Package Discovery

225

226

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.

227

228

### Symlink Creation

229

230

- Links package directories to `node_modules` folders of dependent packages

231

- Links executable files to `.bin` directories for CLI commands

232

- Supports custom source directories via `publishConfig.directory` in package.json

233

- Respects version range matching unless `--force-local` is used

234

235

### Version Range Handling

236

237

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.

238

239

### File Specification Conversion

240

241

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.

242

243

## Integration

244

245

### Lerna Command System

246

247

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

248

- Direct package usage: `require("@lerna/link")`

249

- Lerna CLI: `lerna link`

250

- Programmatic Lerna API

251

252

### Package Manager Compatibility

253

254

- **Supported**: npm, yarn

255

- **Not Supported**: pnpm (throws validation error due to pnpm's automatic workspace linking)

256

257

### Build Integration

258

259

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