UNPKG

mp-lens

Version:

微信小程序分析工具 (Unused Code, Dependencies, Visualization)

241 lines 11.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PathResolver = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const debug_logger_1 = require("./debug-logger"); class PathResolver { constructor(projectRoot, options, aliasResolver, hasAliasConfig) { this.projectRoot = projectRoot; this.options = options; // Store options, especially for miniappRoot this.aliasResolver = aliasResolver; this.hasAliasConfig = hasAliasConfig; } /** * Resolves an import path (which could be relative, absolute, alias, or implicit root) * to an existing file path, considering context-specific allowed extensions. * * @param importPath The original import string (e.g., './utils', '/pages/index', '@/comp', 'image.png'). * @param sourcePath The absolute path of the file containing the import. * @param allowedExtensions An ordered array of extensions to check (e.g., ['.js', '.ts'] or ['.wxml']). * @returns The absolute path of the resolved existing file, or null if not found. */ resolveAnyPath(importPath, sourcePath, allowedExtensions) { debug_logger_1.logger.trace(`Resolving import '${importPath}' from '${sourcePath}' with allowed extensions: [${allowedExtensions.join(', ')}]`); // Rule 0: Handle data URIs and remote URLs if (/^data:/.test(importPath) || /^(http|https|\/\/):/.test(importPath)) { debug_logger_1.logger.trace(`Skipping resolution for data URI or remote URL: ${importPath}`); return null; } if (this.isNpmPackageImport(importPath)) { debug_logger_1.logger.trace(`Skipping resolution for npm package import: ${importPath}`); return null; } if (path.isAbsolute(importPath)) { debug_logger_1.logger.trace(`Input importPath '${importPath}' is absolute. Checking direct existence first.`); const existingAbsolutePath = this.findExistingPath(importPath, allowedExtensions); if (existingAbsolutePath) { debug_logger_1.logger.trace(`Found existing file at true absolute path: ${existingAbsolutePath}. Returning directly.`); return existingAbsolutePath; } else { debug_logger_1.logger.trace(`Absolute path '${importPath}' not found directly. Will proceed to normal resolution (might be root-relative).`); } } let potentialBasePath = null; let isAlias = false; if (this.isAliasPath(importPath) && this.aliasResolver) { isAlias = true; potentialBasePath = this.aliasResolver.resolve(importPath, sourcePath); if (potentialBasePath) { debug_logger_1.logger.trace(`Alias resolved to base path: ${potentialBasePath}`); } else { debug_logger_1.logger.warn(`Alias '${importPath}' detected but could not be resolved by AliasResolver.`); return null; } } if (!potentialBasePath) { const sourceDir = path.dirname(sourcePath); const miniappRoot = this.options.miniappRoot || this.projectRoot; if (importPath.startsWith('/')) { potentialBasePath = path.resolve(miniappRoot, importPath.slice(1)); } else if (importPath.startsWith('.')) { potentialBasePath = path.resolve(sourceDir, importPath); } else { potentialBasePath = path.resolve(miniappRoot, importPath); } debug_logger_1.logger.trace(`Path resolved to potential base path: ${potentialBasePath}`); } if (potentialBasePath) { const existingPath = this.findExistingPath(potentialBasePath, allowedExtensions); if (existingPath) { debug_logger_1.logger.trace(`Resolved '${importPath}' to existing file: ${existingPath}`); return existingPath; } else if (isAlias) { debug_logger_1.logger.warn(`Alias resolved to '${potentialBasePath}', but no existing file found with extensions [${allowedExtensions.join(', ')}]`); } } if (!isAlias) { debug_logger_1.logger.warn(`Failed to resolve import '${importPath}' from '${sourcePath}'.`); } return null; } /** * Given a potential absolute base path (without extension or index), finds the * actual existing file path by checking for the path itself, adding allowed * extensions, or checking for directory index files with allowed extensions. * * @param potentialPath Absolute path, possibly without extension (e.g., '/path/to/file' or '/path/to/dir') * @param allowedExtensions Ordered list of extensions to check (e.g., ['.js', '.ts']) * @returns The existing absolute file path, or null. */ findExistingPath(potentialPath, allowedExtensions) { debug_logger_1.logger.trace(`Looking for existing path: ${potentialPath} with extensions: ${allowedExtensions}`); let potentialPathIsDir = false; try { const stats = fs.statSync(potentialPath); if (stats.isFile()) { debug_logger_1.logger.trace(`Check 1: Exact path exists and is a file: ${potentialPath}`); return potentialPath; // Exact match and is a file } else if (stats.isDirectory()) { debug_logger_1.logger.trace(`Check 1: Exact path exists and is a directory: ${potentialPath}`); potentialPathIsDir = true; // It's a directory, continue to check index files } } catch (e) { debug_logger_1.logger.trace(`Check 1: Exact path does not exist: ${potentialPath}`); } // Check 2: Try appending allowed extensions if it wasn't a directory if (!potentialPathIsDir) { debug_logger_1.logger.trace(`Check 2: Trying extensions for base path: ${potentialPath}`); for (const ext of allowedExtensions) { const pathWithExt = potentialPath + ext; debug_logger_1.logger.trace(`Check 2a: Checking path with extension: ${pathWithExt}`); try { const stats = fs.statSync(pathWithExt); if (stats.isFile()) { debug_logger_1.logger.trace(`Check 2b: Found file with extension: ${pathWithExt}`); return pathWithExt; } else { debug_logger_1.logger.trace(`Check 2b: Path with extension not found or not a file: ${pathWithExt}`); } } catch (e) { debug_logger_1.logger.trace(`Check 2b: Error stating path ${pathWithExt}: ${e.message}`); } } } // Check 3: If the original path was a directory OR it wasn't found with extensions, check for index files debug_logger_1.logger.trace(`Check 3: Checking for index files in directory: ${potentialPath}`); for (const ext of allowedExtensions) { const indexFilePath = path.join(potentialPath, 'index' + ext); debug_logger_1.logger.trace(`Check 3a: Checking index file: ${indexFilePath}`); try { const stats = fs.statSync(indexFilePath); if (stats.isFile()) { debug_logger_1.logger.trace(`Check 3b: Found index file: ${indexFilePath}`); return indexFilePath; } else { debug_logger_1.logger.trace(`Check 3b: Index file not found or not a file: ${indexFilePath}`); } } catch (e) { debug_logger_1.logger.trace(`Check 3b: Error stating index file ${indexFilePath}: ${e.message}`); } } debug_logger_1.logger.trace(`Failed to find existing path for: ${potentialPath}`); return null; // Nothing found } /** * Check if the import path looks like an alias based on the loaded configuration. */ isAliasPath(importPath) { if (!this.hasAliasConfig || !this.aliasResolver) { return false; } const aliases = this.aliasResolver.getAliases(); if (Object.keys(aliases).length === 0) { return false; } if (importPath in aliases) { return true; } for (const alias of Object.keys(aliases)) { if (importPath === alias || importPath.startsWith(`${alias}/`)) { return true; } } return false; } /** * Check if the import path looks like an npm package that we shouldn't try to resolve * on the file system or with aliases. */ isNpmPackageImport(importPath) { // First check: if it's an absolute path, it's definitely not an npm package if (path.isAbsolute(importPath)) { return false; } if (importPath.startsWith('@')) { const scope = importPath.split('/')[0]; if (this.hasAliasConfig && this.aliasResolver) { const aliases = this.aliasResolver.getAliases(); if (scope in aliases || Object.keys(aliases).some((alias) => alias === scope || alias.startsWith(`${scope}/`))) { return false; // It's a configured alias, not necessarily an npm package } } return true; // Starts with @ and doesn't match a configured alias scope } // Basic check: if it doesn't start with '.', '/', or match an alias, it *might* be an npm package. if (!importPath.startsWith('.') && !importPath.startsWith('/') && !this.isAliasPath(importPath)) { debug_logger_1.logger.trace(`Path '${importPath}' is non-relative, non-absolute, non-alias. Considering as NPM package.`); return true; // MODIFIED: Was false, now true for paths like 'lodash' } return false; // Default to false if none of the above conditions met (e.g. relative paths) } } exports.PathResolver = PathResolver; //# sourceMappingURL=path-resolver.js.map