UNPKG

knip

Version:

Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects

66 lines (65 loc) 2.46 kB
import { Visitor } from 'oxc-parser'; import { isInNodeModules } from "../util/path.js"; import { getStringValue, isStringLiteral, stripQuotes } from "./visitors/helpers.js"; const _requireSpecs = []; const _requireVisitor = new Visitor({ CallExpression(node) { if (node.callee?.type === 'Identifier' && node.callee.name === 'require') { const arg = node.arguments?.[0]; if (isStringLiteral(arg)) _requireSpecs.push(getStringValue(arg)); } if (node.callee?.type === 'MemberExpression' && !node.callee.computed && node.callee.object?.type === 'Identifier' && node.callee.object.name === 'require' && node.callee.property?.name === 'resolve') { const arg = node.arguments?.[0]; if (isStringLiteral(arg)) _requireSpecs.push(getStringValue(arg)); } }, TSImportEqualsDeclaration(node) { if (node.moduleReference?.type === 'TSExternalModuleReference') { const expr = node.moduleReference.expression; if (isStringLiteral(expr)) _requireSpecs.push(getStringValue(expr)); } }, }); const _jsDocImportRe = /import\(\s*['"]([^'"]+)['"]\s*\)/g; export function extractSpecifiers(result, sourceText, filePath) { const specifiers = []; const mod = result.module; for (const si of mod.staticImports) { specifiers.push(si.moduleRequest.value); } for (const se of mod.staticExports) { for (const entry of se.entries) { if (entry.moduleRequest) specifiers.push(entry.moduleRequest.value); } } for (const di of mod.dynamicImports) { const cleaned = stripQuotes(sourceText.slice(di.moduleRequest.start, di.moduleRequest.end)); if (cleaned && !cleaned.includes('$') && !cleaned.includes('+')) { specifiers.push(cleaned); } } if (!isInNodeModules(filePath)) { _requireSpecs.length = 0; _requireVisitor.visit(result.program); for (const spec of _requireSpecs) specifiers.push(spec); } for (const comment of result.comments) { if (comment.type !== 'Block') continue; let m; _jsDocImportRe.lastIndex = 0; while ((m = _jsDocImportRe.exec(comment.value)) !== null) { specifiers.push(m[1]); } } return specifiers; }