or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-compilation.mdconfiguration.mddevelopment-integration.mdindex.mdmodule-packaging.mdpackagers.mdutilities.mdwebpack-integration.md

packagers.mddocs/

0

# Packager System

1

2

Package manager abstraction supporting npm and yarn with workspace and monorepo capabilities. The packager system provides a unified interface for different package managers while handling their specific requirements and optimizations.

3

4

## Capabilities

5

6

### Packager Factory

7

8

Factory function for obtaining packager instances.

9

10

```javascript { .api }

11

/**

12

* Get a packager instance by identifier

13

* @param packagerId - Package manager type ('npm' or 'yarn')

14

* @returns Packager instance with static methods

15

*/

16

function get(packagerId: 'npm' | 'yarn'): Packager;

17

```

18

19

**Usage Examples:**

20

21

```javascript

22

const packagers = require('serverless-webpack/lib/packagers');

23

24

// Get npm packager

25

const npm = packagers.get('npm');

26

console.log('NPM lock file:', npm.lockfileName); // 'package-lock.json'

27

28

// Get yarn packager

29

const yarn = packagers.get('yarn');

30

console.log('Yarn lock file:', yarn.lockfileName); // 'yarn.lock'

31

```

32

33

### Packager Interface

34

35

Common interface implemented by all package managers.

36

37

```javascript { .api }

38

interface Packager {

39

/** Name of the lock file used by this packager */

40

static lockfileName: string;

41

42

/** Whether this packager requires copying node_modules */

43

static mustCopyModules: boolean;

44

45

/**

46

* Get sections of package.json to copy during packaging

47

* @param packagerOptions - Configuration options for the packager

48

* @returns Array of package.json section names to copy

49

*/

50

static copyPackageSectionNames(packagerOptions: object): string[];

51

52

/**

53

* Get version information for the package manager

54

* @param cwd - Working directory path

55

* @returns Promise resolving to version object

56

*/

57

static getPackagerVersion(cwd: string): Promise<{version: string}>;

58

59

/**

60

* Get production dependencies from package files

61

* @param cwd - Working directory path

62

* @param depth - Dependency tree depth (optional)

63

* @returns Promise resolving to dependency tree object

64

*/

65

static getProdDependencies(cwd: string, depth?: number): Promise<object>;

66

67

/**

68

* Rebase lock file paths for different directory structure

69

* @param pathToPackageRoot - Path to package root directory

70

* @param lockfile - Lock file object to modify

71

*/

72

static rebaseLockfile(pathToPackageRoot: string, lockfile: object): void;

73

74

/**

75

* Install dependencies using the package manager

76

* @param cwd - Working directory path

77

* @param packagerOptions - Package manager specific options

78

* @returns Promise that resolves when installation completes

79

*/

80

static install(cwd: string, packagerOptions?: object): Promise<void>;

81

82

/**

83

* Remove development dependencies (production-only install)

84

* @param cwd - Working directory path

85

* @param packagerOptions - Package manager specific options

86

* @returns Promise that resolves when pruning completes

87

*/

88

static prune(cwd: string, packagerOptions?: object): Promise<void>;

89

90

/**

91

* Run package.json scripts

92

* @param cwd - Working directory path

93

* @param scriptNames - Array of script names to execute

94

* @returns Promise that resolves when scripts complete

95

*/

96

static runScripts(cwd: string, scriptNames: string[]): Promise<void>;

97

}

98

```

99

100

## NPM Packager

101

102

NPM package manager implementation with support for all NPM versions and package-lock.json handling.

103

104

```javascript { .api }

105

class NPM implements Packager {

106

static lockfileName: 'package-lock.json';

107

static mustCopyModules: false;

108

109

static copyPackageSectionNames(packagerOptions: object): string[];

110

static getPackagerVersion(cwd: string): Promise<{version: string}>;

111

static getProdDependencies(cwd: string, depth?: number): Promise<object>;

112

static rebaseLockfile(pathToPackageRoot: string, lockfile: object): void;

113

static install(cwd: string, packagerOptions?: object): Promise<void>;

114

static prune(cwd: string, packagerOptions?: object): Promise<void>;

115

static runScripts(cwd: string, scriptNames: string[]): Promise<void>;

116

}

117

```

118

119

**Usage Examples:**

120

121

```javascript

122

const packagers = require('serverless-webpack/lib/packagers');

123

const npm = packagers.get('npm');

124

125

// Get NPM version

126

const version = await npm.getPackagerVersion('/path/to/project');

127

console.log('NPM version:', version.version);

128

129

// Install dependencies

130

await npm.install('/path/to/project', {

131

ignoreScripts: true,

132

production: true

133

});

134

135

// Get production dependencies

136

const deps = await npm.getProdDependencies('/path/to/project');

137

console.log('Dependencies:', Object.keys(deps.dependencies));

138

139

// Run custom scripts

140

await npm.runScripts('/path/to/project', ['postinstall', 'prepare']);

141

```

142

143

## Yarn Packager

144

145

Yarn package manager implementation with support for both Yarn Classic (v1) and Yarn Berry (v2+), workspaces, and yarn.lock handling.

146

147

```javascript { .api }

148

class Yarn implements Packager {

149

static lockfileName: 'yarn.lock';

150

static mustCopyModules: true;

151

152

static copyPackageSectionNames(packagerOptions: object): string[];

153

static getPackagerVersion(cwd: string): Promise<{version: string}>;

154

static getProdDependencies(cwd: string, depth?: number): Promise<object>;

155

static rebaseLockfile(pathToPackageRoot: string, lockfile: object): void;

156

static install(cwd: string, packagerOptions?: object): Promise<void>;

157

static prune(cwd: string, packagerOptions?: object): Promise<void>;

158

static runScripts(cwd: string, scriptNames: string[]): Promise<void>;

159

160

/**

161

* Check if this is Yarn Berry (v2+) vs Yarn Classic (v1)

162

* @param version - Yarn version string

163

* @returns True if Yarn Berry, false if Yarn Classic

164

*/

165

static isBerryVersion(version: string): boolean;

166

}

167

```

168

169

**Usage Examples:**

170

171

```javascript

172

const packagers = require('serverless-webpack/lib/packagers');

173

const yarn = packagers.get('yarn');

174

175

// Check Yarn version type

176

const version = await yarn.getPackagerVersion('/path/to/project');

177

const isBerry = yarn.isBerryVersion(version.version);

178

console.log('Using Yarn Berry:', isBerry);

179

180

// Install with yarn-specific options

181

await yarn.install('/path/to/project', {

182

ignoreScripts: false,

183

production: true,

184

frozenLockfile: true

185

});

186

187

// Yarn requires copying node_modules

188

console.log('Must copy modules:', yarn.mustCopyModules); // true

189

190

// Get production dependencies (handles workspaces)

191

const deps = await yarn.getProdDependencies('/path/to/project');

192

```

193

194

## Packager Configuration

195

196

Package managers can be configured through the webpack configuration in serverless.yml.

197

198

```yaml { .api }

199

custom:

200

webpack:

201

packager: 'npm' | 'yarn' # Package manager selection

202

packagerOptions: # Packager-specific options

203

scripts: string[] # Scripts to run after install

204

noInstall: boolean # Skip install step

205

ignoreLockfile: boolean # Ignore lock file during install

206

ignoreScripts: boolean # Skip pre/post install scripts

207

production: boolean # Install only production dependencies

208

frozenLockfile: boolean # Use exact lock file versions (Yarn)

209

[customOption: string]: any # Additional packager-specific options

210

```

211

212

**Configuration Examples:**

213

214

```yaml

215

# NPM configuration with custom options

216

custom:

217

webpack:

218

packager: 'npm'

219

packagerOptions:

220

scripts:

221

- 'rebuild' # Run after install

222

- 'prepare'

223

ignoreScripts: false # Allow pre/post install scripts

224

production: true # Production-only install

225

226

# Yarn configuration with Berry support

227

custom:

228

webpack:

229

packager: 'yarn'

230

packagerOptions:

231

frozenLockfile: true # Use exact lock file versions

232

scripts:

233

- 'postinstall'

234

production: true

235

236

# Yarn workspace configuration

237

custom:

238

webpack:

239

packager: 'yarn'

240

includeModules:

241

packagePath: '../package.json' # Workspace root package.json

242

nodeModulesRelativeDir: '../../' # Shared node_modules location

243

packagerOptions:

244

workspaces: true # Enable workspace support

245

```

246

247

## Advanced Usage Patterns

248

249

### Monorepo and Workspace Support

250

251

Both npm and yarn packagers support monorepo and workspace configurations:

252

253

```javascript

254

// Automatic workspace detection

255

const packagers = require('serverless-webpack/lib/packagers');

256

const yarn = packagers.get('yarn');

257

258

// Yarn automatically handles workspace dependencies

259

const deps = await yarn.getProdDependencies('/workspace/package');

260

261

// Lock file rebasing for different directory structures

262

const lockfileContent = require('/workspace/yarn.lock');

263

yarn.rebaseLockfile('../', lockfileContent);

264

```

265

266

### Custom Packager Options

267

268

Pass custom options to package managers:

269

270

```javascript

271

const npm = packagers.get('npm');

272

273

// Install with custom NPM options

274

await npm.install('/path/to/project', {

275

'ignore-scripts': true,

276

'only': 'production',

277

'no-audit': true,

278

'no-fund': true

279

});

280

```

281

282

### Error Handling

283

284

Packager operations may throw errors for various failure conditions:

285

286

```javascript

287

const { SpawnError } = require('serverless-webpack/lib/utils');

288

289

try {

290

await npm.install('/path/to/project');

291

} catch (error) {

292

if (error instanceof SpawnError) {

293

console.error('Install failed:', error.stderr);

294

console.log('Partial output:', error.stdout);

295

}

296

}

297

```

298

299

## Integration with Module Packaging

300

301

The packager system integrates with the module packaging configuration:

302

303

```yaml

304

custom:

305

webpack:

306

includeModules: true # Enable external module packaging

307

packager: 'yarn' # Use yarn for dependency management

308

packagerOptions:

309

frozenLockfile: true # Yarn-specific option

310

scripts: # Run after dependency install

311

- 'prepare:production'

312

```

313

314

The packager handles:

315

- Installing external dependencies detected by webpack

316

- Running custom scripts for build preparation

317

- Managing lock files for consistent installs

318

- Workspace and monorepo dependency resolution

319

- Production-only dependency filtering

320

321

## Package Manager Detection

322

323

The plugin automatically detects the appropriate package manager based on:

324

1. Explicit `packager` configuration

325

2. Presence of lock files (`package-lock.json` vs `yarn.lock`)

326

3. Workspace configuration in `package.json`

327

328

```javascript

329

// Manual packager selection based on environment

330

const packagers = require('serverless-webpack/lib/packagers');

331

332

const hasYarnLock = fs.existsSync('./yarn.lock');

333

const hasNpmLock = fs.existsSync('./package-lock.json');

334

335

const packager = hasYarnLock ? packagers.get('yarn') : packagers.get('npm');

336

```