Files
NianToB/scripts/assert-electron-runtime-deps.mjs
2026-05-12 19:44:44 +08:00

76 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
import { builtinModules } from 'node:module';
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const ROOT = join(__dirname, '..');
const MAIN_BUNDLE = join(ROOT, 'dist-electron', 'main', 'index.js');
const PACKAGE_JSON = join(ROOT, 'package.json');
const ignoredRuntimeSpecifiers = new Set([
'electron',
...builtinModules,
...builtinModules.map((name) => `node:${name}`),
]);
const packageJson = JSON.parse(readFileSync(PACKAGE_JSON, 'utf8'));
const mainBundle = readFileSync(MAIN_BUNDLE, 'utf8');
function packageNameFromSpecifier(specifier) {
if (
!specifier
|| specifier.startsWith('.')
|| specifier.startsWith('/')
|| ignoredRuntimeSpecifiers.has(specifier)
) {
return undefined;
}
const parts = specifier.split('/');
return specifier.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];
}
function collectRuntimeDependencies() {
const specs = new Set();
const patterns = [
/require\((['"])([^'"]+)\1\)/g,
/import\((['"])([^'"]+)\1\)/g,
];
for (const pattern of patterns) {
let match;
while ((match = pattern.exec(mainBundle))) {
specs.add(match[2]);
}
}
return new Set(
[...specs]
.map(packageNameFromSpecifier)
.filter(Boolean),
);
}
const required = collectRuntimeDependencies();
const packaged = new Set(Object.keys(packageJson.dependencies ?? {}));
const missing = [...required].filter((name) => !packaged.has(name)).sort();
const redundant = [...packaged].filter((name) => !required.has(name)).sort();
if (missing.length || redundant.length) {
console.error('Electron runtime dependency boundary is not clean.');
if (missing.length) {
console.error(`Missing package.json dependencies:\n${missing.map((name) => ` - ${name}`).join('\n')}`);
}
if (redundant.length) {
console.error(`Redundant package.json dependencies that will be double-packed:\n${redundant.map((name) => ` - ${name}`).join('\n')}`);
}
console.error('\nKeep OpenClaw/agent dependencies in devDependencies; bundle-openclaw.mjs copies them into resources/openclaw.');
process.exit(1);
}
console.log(`Electron runtime dependency boundary OK (${packaged.size} package dependencies).`);