UNPKG

@aquaori/deplens

Version:

A precise dependency analysis tool for npm and pnpm projects

137 lines 5.87 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNpmDependencies = getNpmDependencies; const fs_1 = __importDefault(require("fs")); const compare_versions_1 = require("compare-versions"); /** * 获取npm项目的依赖信息 * @param args 命令行参数对象 * @param checkCount 检查计数 * @returns 依赖列表和更新后的检查计数 */ async function getNpmDependencies(args, checkCount) { // 确定npm依赖锁文件路径 const manifestPath = `${args.path}/package-lock.json`; // 检查锁文件是否存在 if (!fs_1.default.existsSync(manifestPath)) { const hint = `The ${args.path}/package-lock.json file does not exist, so dependencies cannot be resolved.\n> If your project dependencies are managed by pnpm, please run deplens with the --pnpm or --pn option.`; throw new Error(hint); } // 解析锁文件 const rootManifest = JSON.parse(fs_1.default.readFileSync(manifestPath, 'utf-8')); // 获取不同类型的依赖 const rootProd = rootManifest["packages"][""].dependencies || {}; const rootPeer = rootManifest["packages"][""].peerDependencies || {}; const rootOpt = rootManifest["packages"][""].optionalDependencies || {}; const rootDev = rootManifest["packages"][""].devDependencies || {}; delete rootManifest["packages"][""]; const depSource = rootManifest["packages"]; // 收集被其他包使用的依赖 const usedByOthers = new Map(); for (const [key, pkg] of Object.entries(depSource)) { if (key === '' || !pkg || typeof pkg !== 'object') continue; const p = pkg; [ p.dependencies || {}, p.peerDependencies || {}, p.optionalDependencies || {} ].forEach(obj => { Object.entries(obj).forEach(([depName, depRange]) => { if (typeof depRange !== 'string') return; const ver = depRange.replace(/\(.+?\)+/g, ''); if (!usedByOthers.has(depName)) usedByOthers.set(depName, new Set()); usedByOthers.get(depName).add(ver); checkCount++; }); }); } // 构建锁文件中的依赖包列表 const lockFilePkg = []; const rootDeclared = new Map(); Object.entries({ ...rootProd, ...rootPeer, ...rootOpt, ...rootDev }) .forEach(([name, ver]) => rootDeclared.set(name, ver)); for (const [name, version] of rootDeclared) { let ignoreList = []; // 处理配置文件中指定的忽略依赖 if (args['config'] !== "" || fs_1.default.existsSync(`${args.path}/deplens.config.json`)) { const configPath = args['config'] || `${args.path}/deplens.config.json`; const config = fs_1.default.readFileSync(configPath, 'utf8'); const ignore = JSON.parse(config).ignoreDep || []; ignoreList = [...ignoreList, ...ignore]; } // 处理命令行参数中指定的忽略依赖 if (args['ignoreDep'] !== "") { const ignoreListFromArgs = args['ignoreDep'].split(','); ignoreList = [...ignoreList, ...ignoreListFromArgs]; } if (ignoreList.includes(name)) continue; // 获取纯净版本号 const pureVersion = version.replace(/[\^\*\~\=\>\<]/g, ''); // 处理使用的版本列表 const usedVersions = usedByOthers.get(name); const usedVersionsList = new Set(); for (let ver of usedVersions || []) { const verList = ver ? ver.split(" || ") : []; for (let ver of verList) { const verName = ver; if (verName != "") usedVersionsList.add(verName); } } // 检查依赖是否被使用 let isUsed = usedVersionsList.has(pureVersion); for (let ver of usedVersionsList) { if (ver == "*") { isUsed = true; break; } if ((0, compare_versions_1.satisfies)(pureVersion, ver)) { isUsed = true; break; } } if (!isUsed) { const preciseVersion = version.replace(/\(.+?\)+/g, ''); const previousPkgIndex = lockFilePkg.findIndex(dep => dep.name == name); const previousPkg = previousPkgIndex >= 0 ? lockFilePkg[previousPkgIndex] : null; let previousVersion = previousPkg?.version ?? []; if (previousPkg !== null && previousVersion !== "") { if (previousVersion.length != 0 && !previousPkg?.usage) { previousVersion = [...previousVersion, preciseVersion]; } else { previousVersion = [preciseVersion]; } } else { previousVersion = [preciseVersion]; } if (previousVersion.length != 1) { previousVersion = [previousVersion.join(" & @")]; } if (previousPkgIndex >= 0 && previousPkg !== null) { lockFilePkg[previousPkgIndex].version = previousVersion; } else { lockFilePkg.push({ name, type: '', version: previousVersion, usage: isUsed, isDev: Object.prototype.hasOwnProperty.call(rootDev, name) }); } } } // 按名称排序 lockFilePkg.sort((a, b) => a.name.localeCompare(b.name)); return [lockFilePkg, checkCount]; } //# sourceMappingURL=npm.js.map