Exports util functions to clean up node_modules
npx @tessl/cli install tessl/npm-pnpm--modules-cleaner@1001.0.0@pnpm/modules-cleaner provides utility functions for cleaning up node_modules directories in pnpm-managed projects. The main functionality is pruning redundant packages by comparing wanted and current lockfiles to remove packages that are no longer needed.
pnpm install @pnpm/modules-cleanerimport { prune } from "@pnpm/modules-cleaner";For CommonJS:
const { prune } = require("@pnpm/modules-cleaner");import { prune } from "@pnpm/modules-cleaner";
import type { LockfileObject } from "@pnpm/lockfile.types";
import type { StoreController } from "@pnpm/store-controller-types";
// Example pruning operation
const removedPackages = await prune(
[
{
binsDir: "/project/node_modules/.bin",
id: ".",
modulesDir: "/project/node_modules",
pruneDirectDependencies: true,
rootDir: "/project"
}
],
{
include: {
dependencies: true,
devDependencies: false,
optionalDependencies: true
},
hoistedDependencies: {},
wantedLockfile: wantedLockfile,
currentLockfile: currentLockfile,
skipped: new Set(),
virtualStoreDir: "/project/node_modules/.pnpm",
virtualStoreDirMaxLength: 120,
lockfileDir: "/project",
storeController: storeController
}
);
console.log(`Removed ${removedPackages.size} packages`);Compares the wanted lockfile with the current one and removes redundant packages from node_modules. This is the main exported function that handles cleanup of unnecessary dependencies.
/**
* Prunes redundant packages from node_modules by comparing wanted and current lockfiles
* @param importers - Array of importer configurations defining projects to clean
* @param opts - Configuration options for pruning operation
* @returns Promise resolving to Set of orphaned dependency paths that were processed
*/
function prune(
importers: Array<{
/** Directory containing binary files for the project */
binsDir: string;
/** Project identifier, typically "." for root project */
id: ProjectId;
/** Directory containing node_modules for the project */
modulesDir: string;
/** Whether to prune direct dependencies */
pruneDirectDependencies?: boolean;
/** Specific packages to remove */
removePackages?: string[];
/** Root directory of the project */
rootDir: ProjectRootDir;
}>,
opts: {
/** Whether to deduplicate direct dependencies */
dedupeDirectDeps?: boolean;
/** If true, only simulate the operation without making changes */
dryRun?: boolean;
/** Which dependency types to include in pruning */
include: { [dependenciesField in DependenciesField]: boolean };
/** Map of hoisted dependencies by dependency path */
hoistedDependencies: HoistedDependencies;
/** Directory for hoisted modules */
hoistedModulesDir?: string;
/** Directory for publicly hoisted modules */
publicHoistedModulesDir?: string;
/** The desired state lockfile */
wantedLockfile: LockfileObject;
/** The current state lockfile */
currentLockfile: LockfileObject;
/** Whether to prune the store */
pruneStore?: boolean;
/** Whether to prune the virtual store */
pruneVirtualStore?: boolean;
/** Set of dependency paths to skip */
skipped: Set<DepPath>;
/** Directory containing the virtual store */
virtualStoreDir: string;
/** Maximum length for virtual store directory names */
virtualStoreDirMaxLength: number;
/** Directory containing the lockfile */
lockfileDir: string;
/** Store controller for package operations */
storeController: StoreController;
}
): Promise<Set<string>>;Note: Most types used by this package are re-exported from other @pnpm ecosystem packages. The definitions below show the essential structure needed for using the prune function. For complete type details, import directly from the source packages.
// Core types from @pnpm/types
type ProjectId = string;
type ProjectRootDir = string;
type DepPath = string;
type DependenciesField = "dependencies" | "devDependencies" | "optionalDependencies";
interface HoistedDependencies {
[depPath: string]: {
[alias: string]: "public" | "private";
};
}
// Lockfile types from @pnpm/lockfile.types
interface LockfileObject {
importers: Record<ProjectId, ProjectSnapshot>;
packages?: PackageSnapshots;
lockfileVersion: string;
// Additional properties may be present
}
interface ProjectSnapshot {
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
// Additional dependency types and properties may be present
}
interface PackageSnapshots {
[packagePath: string]: PackageSnapshot;
}
interface PackageSnapshot {
resolution: {
integrity?: string;
tarball?: string;
// Additional resolution properties may be present
};
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
optionalDependencies?: Record<string, string>;
// Additional dependency types and properties may be present
}
// Store controller type from @pnpm/store-controller-types
interface StoreController {
requestPackage: RequestPackageFunction;
fetchPackage: FetchPackageToStoreFunction | FetchPackageToStoreFunctionAsync;
getFilesIndexFilePath: GetFilesIndexFilePath;
importPackage: ImportPackageFunctionAsync;
close(): Promise<void>;
prune(removeAlienFiles?: boolean): Promise<void>;
upload: UploadPkgToStore;
clearResolutionCache(): void;
}
// Note: RequestPackageFunction, FetchPackageToStoreFunction, and other complex types
// are available from @pnpm/store-controller-types. Import them directly for complete signatures.