// 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 ===`);