or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm--pnpm--modules-cleaner

Utilities for cleaning up node_modules directories in pnpm-managed projects

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@pnpm/modules-cleaner@1000.0.x

To install, run

npx @tessl/cli install tessl/npm--pnpm--modules-cleaner@1000.0.0

0

# @pnpm/modules-cleaner

1

2

@pnpm/modules-cleaner provides utilities for cleaning up node_modules directories in pnpm-managed projects. It offers functionality to compare lockfiles and remove redundant packages from node_modules, helping maintain clean and optimized package installations within the pnpm ecosystem.

3

4

## Package Information

5

6

- **Package Name**: @pnpm/modules-cleaner

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `pnpm install @pnpm/modules-cleaner`

10

- **Node.js**: >=18.12

11

- **License**: MIT

12

- **Peer Dependencies**: @pnpm/logger (>=5.1.0 <1001.0.0)

13

14

## Core Imports

15

16

```typescript

17

import { prune } from "@pnpm/modules-cleaner";

18

```

19

20

For CommonJS:

21

22

```javascript

23

const { prune } = require("@pnpm/modules-cleaner");

24

```

25

26

Advanced imports (for direct access to utility functions):

27

28

```typescript

29

import { removeDirectDependency, removeIfEmpty } from "@pnpm/modules-cleaner/lib/removeDirectDependency";

30

```

31

32

## Basic Usage

33

34

```typescript

35

import { prune } from "@pnpm/modules-cleaner";

36

import type {

37

Lockfile,

38

StoreController,

39

HoistedDependencies,

40

ProjectId,

41

ProjectRootDir,

42

DepPath

43

} from "@pnpm/types";

44

45

// Assume you have lockfile objects and store controller available

46

declare const wantedLockfile: Lockfile;

47

declare const currentLockfile: Lockfile;

48

declare const storeController: StoreController;

49

50

// Basic pruning operation

51

const removedPaths = await prune(

52

[

53

{

54

binsDir: "/project/node_modules/.bin",

55

id: "project-id" as ProjectId,

56

modulesDir: "/project/node_modules",

57

rootDir: "/project" as ProjectRootDir,

58

},

59

],

60

{

61

include: {

62

dependencies: true,

63

devDependencies: true,

64

optionalDependencies: true

65

},

66

hoistedDependencies: new Map() as HoistedDependencies,

67

wantedLockfile,

68

currentLockfile,

69

skipped: new Set<DepPath>(),

70

virtualStoreDir: "/project/node_modules/.pnpm",

71

virtualStoreDirMaxLength: 120,

72

lockfileDir: "/project",

73

storeController,

74

}

75

);

76

```

77

78

## Capabilities

79

80

### Package Pruning

81

82

Compares the wanted lockfile with the current one and removes redundant packages from node_modules that are no longer needed.

83

84

```typescript { .api }

85

/**

86

* Compares the wanted lockfile with the current one and removes redundant packages from node_modules

87

* @param importers - Array of project configurations to prune

88

* @param opts - Pruning options and configuration

89

* @returns Promise that resolves to a Set of removed package paths

90

*/

91

async function prune(

92

importers: Array<{

93

/** Directory containing binary files for the project */

94

binsDir: string;

95

/** Unique identifier for the project */

96

id: ProjectId;

97

/** Path to the node_modules directory */

98

modulesDir: string;

99

/** Whether to prune direct dependencies */

100

pruneDirectDependencies?: boolean;

101

/** Specific packages to remove */

102

removePackages?: string[];

103

/** Root directory of the project */

104

rootDir: ProjectRootDir;

105

}>,

106

opts: {

107

/** Whether to deduplicate direct dependencies */

108

dedupeDirectDeps?: boolean;

109

/** Run in dry-run mode without actually removing files */

110

dryRun?: boolean;

111

/** Specify which dependency types to include in pruning */

112

include: { [dependenciesField in DependenciesField]: boolean };

113

/** Map of hoisted dependencies */

114

hoistedDependencies: HoistedDependencies;

115

/** Directory for hoisted modules */

116

hoistedModulesDir?: string;

117

/** Directory for publicly hoisted modules */

118

publicHoistedModulesDir?: string;

119

/** The desired lockfile state */

120

wantedLockfile: Lockfile;

121

/** The current lockfile state */

122

currentLockfile: Lockfile;

123

/** Whether to prune the store */

124

pruneStore?: boolean;

125

/** Whether to prune the virtual store */

126

pruneVirtualStore?: boolean;

127

/** Set of dependency paths to skip */

128

skipped: Set<DepPath>;

129

/** Path to the virtual store directory */

130

virtualStoreDir: string;

131

/** Maximum length for virtual store directory paths */

132

virtualStoreDirMaxLength: number;

133

/** Directory containing the lockfile */

134

lockfileDir: string;

135

/** Store controller for package management */

136

storeController: StoreController;

137

}

138

): Promise<Set<string>>;

139

```

140

141

### Direct Dependency Removal

142

143

Specifically removes a single direct dependency from a project's node_modules directory, including its binary files.

144

145

```typescript { .api }

146

/**

147

* Removes a specific direct dependency from node_modules

148

* @param dependency - The dependency to remove with optional metadata

149

* @param opts - Configuration options for removal operation

150

* @returns Promise that resolves when removal is complete

151

*/

152

async function removeDirectDependency(

153

dependency: {

154

/** The type of dependency field this came from */

155

dependenciesField?: DependenciesField | undefined;

156

/** Name of the package to remove */

157

name: string;

158

},

159

opts: {

160

/** Directory containing binary files for the project */

161

binsDir: string;

162

/** Run in dry-run mode without actually removing files */

163

dryRun?: boolean;

164

/** Path to the node_modules directory */

165

modulesDir: string;

166

/** Whether to suppress removal logs */

167

muteLogs?: boolean;

168

/** Root directory of the project */

169

rootDir: ProjectRootDir;

170

}

171

): Promise<void>;

172

```

173

174

### Empty Directory Removal

175

176

Utility function to remove a directory only if it's empty.

177

178

```typescript { .api }

179

/**

180

* Removes a directory if it's empty

181

* @param dir - Path to directory to potentially remove

182

* @returns Promise that resolves when operation is complete

183

*/

184

async function removeIfEmpty(dir: string): Promise<void>;

185

```

186

187

## Types

188

189

```typescript { .api }

190

// Core type definitions used by the API

191

192

/** Unique identifier for a project */

193

type ProjectId = string & { readonly __brand: unique symbol };

194

195

/** Root directory path for a project */

196

type ProjectRootDir = string & { readonly __brand: unique symbol };

197

198

/** Dependency path identifier */

199

type DepPath = string & { readonly __brand: unique symbol };

200

201

/** Map of hoisted dependencies */

202

type HoistedDependencies = Map<string, string[]>;

203

204

/** Fields that can contain dependencies in package.json */

205

type DependenciesField = 'dependencies' | 'devDependencies' | 'optionalDependencies';

206

207

/** Lockfile structure containing package information */

208

interface Lockfile {

209

version: string;

210

packages?: PackageSnapshots;

211

importers?: Record<string, ProjectSnapshot>;

212

// Additional lockfile properties...

213

}

214

215

/** Package snapshots containing dependency information */

216

type PackageSnapshots = Record<string, PackageSnapshot>;

217

218

/** Individual package snapshot with dependency metadata */

219

interface PackageSnapshot {

220

resolution?: { integrity?: string; tarball?: string };

221

dependencies?: Record<string, string>;

222

optionalDependencies?: Record<string, string>;

223

// Additional snapshot properties...

224

}

225

226

/** Project snapshot containing project-specific dependency information */

227

interface ProjectSnapshot {

228

dependencies?: Record<string, string>;

229

devDependencies?: Record<string, string>;

230

optionalDependencies?: Record<string, string>;

231

// Additional project properties...

232

}

233

234

/** Store controller interface for package management operations */

235

interface StoreController {

236

close(): Promise<void>;

237

fetchPackage(fetchPackageOpts: any): Promise<any>;

238

requestPackage(requestPackageOpts: any): Promise<any>;

239

upload(builtPkgLocation: string, opts: any): Promise<void>;

240

}

241

```

242

243

## Related Modules

244

245

This package also includes additional utility functions that can be imported directly from their modules:

246

247

- `removeDirectDependency`: Available from `@pnpm/modules-cleaner/lib/removeDirectDependency` - Removes a specific direct dependency from node_modules

248

- `removeIfEmpty`: Available from `@pnpm/modules-cleaner/lib/removeDirectDependency` - Removes a directory if it's empty

249

250

The main `prune` function utilizes these utilities internally as part of its comprehensive cleanup process.