TypeScript library that analyzes pnpm lockfiles to classify dependencies into different types (development-only, production-only, or both)
npx @tessl/cli install tessl/npm-pnpm--lockfile-detect-dep-types@1001.0.0A TypeScript library that analyzes pnpm lockfiles to classify dependencies into different types: development-only, production-only, or both development and production dependencies. This utility is specifically designed for pnpm's lockfile format and is used internally by pnpm tooling to optimize dependency installation and bundling processes.
pnpm add @pnpm/lockfile.detect-dep-typesimport { detectDepTypes, DepType, type DepTypes } from "@pnpm/lockfile.detect-dep-types";CommonJS:
const { detectDepTypes, DepType } = require("@pnpm/lockfile.detect-dep-types");import { detectDepTypes, DepType, type DepTypes } from "@pnpm/lockfile.detect-dep-types";
import { type LockfileObject } from "@pnpm/lockfile.types";
// Analyze a pnpm lockfile to classify dependencies
const lockfile: LockfileObject = {
lockfileVersion: "9.0",
importers: {
".": {
specifiers: {
"lodash": "^4.17.21",
"typescript": "^5.0.0"
},
dependencies: {
"lodash": "4.17.21"
},
devDependencies: {
"typescript": "5.0.2"
}
}
},
packages: {
"lodash@4.17.21": {
resolution: { integrity: "sha512-..." }
},
"typescript@5.0.2": {
resolution: { integrity: "sha512-..." }
}
}
};
// Detect dependency types
const depTypes: DepTypes = detectDepTypes(lockfile);
// Check individual dependency classifications
if (depTypes["lodash@4.17.21"] === DepType.ProdOnly) {
console.log("lodash is production-only");
}
if (depTypes["typescript@5.0.2"] === DepType.DevOnly) {
console.log("typescript is development-only");
}Analyzes pnpm lockfiles to classify each dependency as development-only, production-only, or used in both environments.
function detectDepTypes(lockfile: LockfileObject): DepTypes;Parameters:
lockfile: LockfileObject - The pnpm lockfile data structure to analyzeReturns:
DepTypes - A record mapping dependency paths to their classificationsUsage Example:
import { detectDepTypes } from "@pnpm/lockfile.detect-dep-types";
const depTypes = detectDepTypes(lockfile);
// Returns object like: { "package@1.0.0": DepType.ProdOnly, "devtool@2.0.0": DepType.DevOnly }Enumeration defining the three possible dependency classifications.
enum DepType {
DevOnly,
DevAndProd,
ProdOnly
}Values:
DepType.DevOnly - Dependencies only used in development environmentsDepType.DevAndProd - Dependencies used in both development and production environmentsDepType.ProdOnly - Dependencies only used in production environmentsUsage Example:
import { DepType } from "@pnpm/lockfile.detect-dep-types";
// Check if a dependency is production-only
if (depTypes["some-package@1.0.0"] === DepType.ProdOnly) {
console.log("This package is needed in production");
}/**
* Record mapping dependency paths to their type classifications
*/
type DepTypes = Record<string, DepType>;
/**
* Dependency path string (from @pnpm/types)
*/
type DepPath = string & { __brand: 'DepPath' };
/**
* Pnpm lockfile object structure (from @pnpm/lockfile.types)
*/
interface LockfileObject {
lockfileVersion: string;
importers: Record<string, ProjectSnapshot>;
packages?: PackageSnapshots;
// ... other lockfile properties
}
/**
* Project snapshot containing dependency information
*/
interface ProjectSnapshot {
specifiers: ResolvedDependencies;
dependencies?: ResolvedDependencies;
optionalDependencies?: ResolvedDependencies;
devDependencies?: ResolvedDependencies;
}
/**
* Resolved dependency mappings
*/
type ResolvedDependencies = Record<string, string>;
/**
* Collection of package snapshots
*/
interface PackageSnapshots {
[packagePath: string]: PackageSnapshot;
}
/**
* Individual package snapshot with metadata
*/
interface PackageSnapshot {
resolution: LockfileResolution;
dependencies?: ResolvedDependencies;
optionalDependencies?: ResolvedDependencies;
// ... other package properties
}The library uses a graph traversal algorithm to analyze dependency relationships:
The analysis considers the entire dependency tree, not just direct dependencies, ensuring that transitive dependencies are properly classified based on how they're ultimately used in the project.