mp-lens
Version:
微信小程序分析工具 (Unused Code, Dependencies, Visualization)
147 lines • 5.83 kB
JavaScript
;
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;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JavaScriptParser = void 0;
const parser_1 = require("@babel/parser");
const traverse_1 = __importDefault(require("@babel/traverse"));
const t = __importStar(require("@babel/types"));
const path = __importStar(require("path"));
const debug_logger_1 = require("../utils/debug-logger");
class JavaScriptParser {
constructor() {
// No dependencies needed for pure text analysis
}
async parse(content, filePath) {
try {
const dependencies = new Set();
// Parse the file content to AST
const ast = this.parseToAST(content, filePath);
// Traverse AST to find import/require statements
this.traverseAST(ast, dependencies);
return Array.from(dependencies);
}
catch (e) {
// Log the error but re-throw it so the central handler in FileParser catches it
debug_logger_1.logger.warn(`Error parsing JavaScript file ${filePath}: ${e.message}`);
throw e; // Re-throw the error
}
}
parseToAST(content, filePath) {
const isTypeScript = path.extname(filePath) === '.ts';
const basePlugins = [
'jsx',
'objectRestSpread',
'functionBind',
'exportDefaultFrom',
'exportNamespaceFrom',
'decorators-legacy',
'classProperties',
'asyncGenerators',
'functionSent',
'dynamicImport',
'numericSeparator',
'optionalChaining',
'importMeta',
'bigInt',
'optionalCatchBinding',
'throwExpressions',
'nullishCoalescingOperator',
'topLevelAwait',
];
const plugins = isTypeScript ? [...basePlugins, 'typescript'] : basePlugins;
try {
return (0, parser_1.parse)(content, {
sourceType: 'module',
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
plugins,
});
}
catch (parseError) {
// If parsing as module fails, check if it contains import/export
const hasImportExport = /\b(import|export)\b/.test(content);
if (hasImportExport) {
// If it has import/export but failed to parse as module, re-throw the error
throw parseError;
}
// If no import/export, try as script
debug_logger_1.logger.trace(`Failed to parse ${filePath} as module, trying as script: ${parseError}`);
return (0, parser_1.parse)(content, {
sourceType: 'script',
allowReturnOutsideFunction: true,
plugins,
});
}
}
traverseAST(ast, dependencies) {
(0, traverse_1.default)(ast, {
// Handle ES6 import statements
ImportDeclaration: (path) => {
const source = path.node.source;
if (t.isStringLiteral(source)) {
const importPath = source.value;
dependencies.add(importPath);
}
},
// Handle CommonJS require() calls
CallExpression: (path) => {
const { node } = path;
// Check if it's a require() call
if (t.isIdentifier(node.callee) &&
node.callee.name === 'require' &&
node.arguments.length === 1 &&
t.isStringLiteral(node.arguments[0])) {
const requirePath = node.arguments[0].value;
dependencies.add(requirePath);
}
},
// Handle dynamic imports
Import: (path) => {
const parent = path.parent;
if (t.isCallExpression(parent) &&
parent.arguments.length === 1 &&
t.isStringLiteral(parent.arguments[0])) {
const importPath = parent.arguments[0].value;
dependencies.add(importPath);
}
},
});
}
}
exports.JavaScriptParser = JavaScriptParser;
//# sourceMappingURL=javascript-parser.js.map