mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 16:30:29 +08:00
7b2bd307f1
- backend/: 13 Maven modules (cw-elevator-application, cloudwalk-cloud, intelligent-cwoscomponent, ninca-crk, etc.) - frontend/: 4 Vue projects (elevator-front, cwos-portal, alarm-front, front_acs) + decompiled + scripts - scripts/: build, test-env, tools (Docker Compose, service templates, API parity) - docs/: AGENTS.md, superpowers specs, architecture docs - .gitignore: standard Java/Maven exclusions Moved from legacy maven-*/ root layout to backend/ organized structure.
100 lines
3.2 KiB
JavaScript
Executable File
100 lines
3.2 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* webpack bundle 解包器
|
|
* 识别 __webpack_modules__ 结构,按模块 ID 拆分为独立文件
|
|
*
|
|
* 用法: node unpack-webpack.js <bundle.js> <output-dir>
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
function unpackWebpackBundle(bundlePath, outputDir) {
|
|
const code = fs.readFileSync(bundlePath, 'utf-8');
|
|
|
|
let modules = null;
|
|
|
|
// 模式1: __webpack_modules__ = { 123: function(module, exports, __webpack_require__) {...}, ... }
|
|
const modulesAssignMatch = code.match(/__webpack_modules__\s*=\s*(\{[\s\S]*?\});/);
|
|
// 模式2: (function(modules) { ... })({ 123: function(...) {...}, ... })
|
|
// Use more flexible matching to cover variations in the bundle.
|
|
const iifeMatch = code.match(/\(function\(\s*\w+\s*\)\s*\{[\s\S]*?\}\s*\)\s*\(\s*(\{[\s\S]*?\})\s*\)\s*;?/);
|
|
// Pattern 3: (function(e){var t={}; ...})({123:function(...)...}) - more compressed IIFE forms
|
|
const compressedIifeMatch = code.match(/\(function\s*\(\w+\)\s*\{[\s\S]*?\}\s*\)\s*\(\s*(\{[\s\S]*?\d+\s*:\s*function[\s\S]*?\})\s*\)/);
|
|
|
|
if (modulesAssignMatch) {
|
|
modules = eval('(' + modulesAssignMatch[1] + ')');
|
|
} else if (iifeMatch) {
|
|
modules = eval('(' + iifeMatch[1] + ')');
|
|
} else if (compressedIifeMatch) {
|
|
modules = eval('(' + compressedIifeMatch[1] + ')');
|
|
} else {
|
|
console.error('未识别到 webpack 模块结构,尝试按 function(module, exports) 正则提取');
|
|
modules = extractByRegex(code);
|
|
}
|
|
|
|
if (!modules || Object.keys(modules).length === 0) {
|
|
console.error('未能提取任何模块');
|
|
process.exit(1);
|
|
}
|
|
|
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
|
|
let count = 0;
|
|
for (const [id, factory] of Object.entries(modules)) {
|
|
const moduleCode = typeof factory === 'function'
|
|
? factory.toString()
|
|
: JSON.stringify(factory, null, 2);
|
|
|
|
const safeId = String(id).replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
fs.writeFileSync(path.join(outputDir, `module_${safeId}.js`), moduleCode);
|
|
count++;
|
|
}
|
|
|
|
console.log(`拆解完成: ${count} 个模块 → ${outputDir}`);
|
|
return count;
|
|
}
|
|
|
|
function extractByRegex(code) {
|
|
const modules = {};
|
|
const re = /(\d+):\s*function\s*\(\s*\w+\s*,\s*\w+\s*,\s*\w+\s*\)\s*\{/g;
|
|
|
|
let match;
|
|
const matches = [];
|
|
|
|
while ((match = re.exec(code)) !== null) {
|
|
// Store match length to avoid treating object as array later
|
|
matches.push({ id: match[1], start: match.index, matchLength: match[0].length });
|
|
}
|
|
|
|
for (let i = 0; i < matches.length; i++) {
|
|
const current = matches[i];
|
|
const next = matches[i + 1];
|
|
const startIdx = current.start;
|
|
const endIdx = next ? next.start : code.length;
|
|
|
|
let depth = 1;
|
|
// Use stored matchLength for correct offset
|
|
let pos = startIdx + (current.matchLength || 0);
|
|
while (depth > 0 && pos < endIdx) {
|
|
if (code[pos] === '{') depth++;
|
|
if (code[pos] === '}') depth--;
|
|
pos++;
|
|
}
|
|
|
|
const funcBody = code.substring(startIdx, pos);
|
|
modules[current.id] = funcBody;
|
|
}
|
|
|
|
return modules;
|
|
}
|
|
|
|
// CLI
|
|
const args = process.argv.slice(2);
|
|
if (args.length < 2) {
|
|
console.log('用法: node unpack-webpack.js <bundle.js> <output-dir>');
|
|
process.exit(1);
|
|
}
|
|
|
|
unpackWebpackBundle(args[0], args[1]);
|