Files
Psychotoxical-psysonic/scripts/check-boot-chunk-lucide.mjs
T

73 lines
2.2 KiB
JavaScript

#!/usr/bin/env node
/**
* Post-build guard: boot-adjacent Vite chunks must not bundle lucide-react.
*
* When a store/utils barrel accidentally re-exports UI, Rollup may pull
* createLucideIcon into authStore/offline chunks and hit TDZ init-order bugs
* in production (Windows WebView2: "X is not a function" on splash).
*
* Run after `npm run build` — no Tauri compile needed.
*/
import { readdirSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
const DIST = join(new URL('..', import.meta.url).pathname, 'dist/assets');
/** Chunk filename prefixes that must stay lucide-free. */
const BOOT_CHUNK_PREFIXES = ['authStore-', 'offline-'];
/** Minified bundles still embed lucide module paths or icon factory calls. */
const LUCIDE_SIGNALS = [
'lucide-react',
'createLucideIcon',
// Common preset/offline icons pulled through bad barrels (minified arg strings):
'("globe"',
'("settings"',
'("wifi-off"',
'("download"',
];
/** Subsonic client id must be a compile-time literal, not a cyclic package.json import. */
const CLIENT_ID_SIGNALS = [
'psysonic/undefined',
'psysonic/${',
];
let files;
try {
files = readdirSync(DIST).filter(f => f.endsWith('.js'));
} catch {
console.error('check-boot-chunk-lucide: dist/assets not found — run `npm run build` first.');
process.exit(1);
}
const violations = [];
for (const file of files) {
if (!BOOT_CHUNK_PREFIXES.some(p => file.startsWith(p))) continue;
const text = readFileSync(join(DIST, file), 'utf8');
for (const signal of LUCIDE_SIGNALS) {
if (text.includes(signal)) {
violations.push({ file, signal });
}
}
for (const signal of CLIENT_ID_SIGNALS) {
if (text.includes(signal)) {
violations.push({ file, signal: `client-id: ${signal}` });
}
}
}
if (violations.length > 0) {
console.error('Lucide leaked into boot-critical chunks:\n');
for (const { file, signal } of violations) {
console.error(` • dist/assets/${file} — matched "${signal}"`);
}
console.error(
'\nFix: split UI from the feature root barrel; import UI from @/features/<x>/ui only in components.',
);
process.exit(1);
}
console.log('check-boot-chunk-lucide: ok');