Files
competition-website/auto-patch-egg.js

66 lines
2.5 KiB
JavaScript
Raw Permalink Normal View History

// auto-patch-egg.js (v3)
const fs = require('fs');
const path = require('path');
const BASE = path.resolve(__dirname, 'node_modules');
const TARGET_DIRS = ['egg', 'egg-cluster', 'cluster-client', 'egg-sequelize', 'egg-logger', 'egg-cors', 'egg-security', 'egg-onerror', 'egg-session', 'egg-view', 'egg-validate', 'egg-jsonp'];
const BUILTINS = new Set([
'fs', 'path', 'os', 'util', 'events', 'stream', 'crypto', 'url', 'http', 'https',
'net', 'tls', 'buffer', 'assert', 'process', 'v8', 'vm', 'zlib', 'querystring',
'child_process', 'cluster', 'dns', 'dgram', 'readline', 'repl', 'string_decoder',
'timers', 'tty', 'domain', 'module', 'console', 'perf_hooks', 'async_hooks',
'worker_threads', 'inspector', 'trace_events', 'wasi',
]);
function findRequires(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf8');
const re = /require\(['"]([^./][^'"]*)['"]\)/g;
const modules = new Set(); let match;
while ((match = re.exec(content)) !== null) {
const name = match[1].split('/')[0];
if (!BUILTINS.has(name)) modules.add(name);
}
return modules;
} catch { return new Set(); }
}
function moduleExists(name) {
try { require.resolve(name, { paths: [BASE] }); return true; } catch { return false; }
}
function walkDir(dir) {
const results = [];
try {
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, e.name);
if (e.isDirectory() && e.name !== 'node_modules') results.push(...walkDir(full));
else if (e.isFile() && /\.(js|cjs)$/.test(e.name) && !e.name.includes('.test.')) results.push(full);
}
} catch {}
return results;
}
function createShim(name) {
const dir = path.join(BASE, name);
if (fs.existsSync(dir)) return false;
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({ name, version: '0.0.1-shim', main: 'index.js' }, null, 2));
fs.writeFileSync(path.join(dir, 'index.js'), `'use strict';module.exports={};`);
return true;
}
console.log('=== 扫描依赖树 ===');
const allRequires = new Set();
for (const target of TARGET_DIRS) {
const targetDir = path.join(BASE, target);
if (!fs.existsSync(targetDir)) continue;
const files = walkDir(targetDir);
for (const f of files) { const reqs = findRequires(f); reqs.forEach(r => allRequires.add(r)); }
}
let count = 0;
for (const mod of allRequires) {
if (!moduleExists(mod)) { if (createShim(mod)) count++; }
}
console.log(`=== 创建 ${count} 个 shim ===`);