feat(platform): harden telemetry pipeline and unify Semi UI workspaces
This commit is contained in:
@@ -6,9 +6,12 @@ const assets = readdirSync(assetsDirectory);
|
||||
const excelAssets = assets.filter((name) => /^exceljs(?:\.min)?-[\w-]+\.js$/.test(name));
|
||||
const mileageWorkers = assets.filter((name) => /^mileageExport\.worker-[\w-]+\.js$/.test(name));
|
||||
const monitorAssets = assets.filter((name) => /^MonitorPage-[\w-]+\.js$/.test(name));
|
||||
const vehicleAssets = assets.filter((name) => /^VehiclePage-[\w-]+\.js$/.test(name));
|
||||
const profileSyncAssets = assets.filter((name) => /^VehicleProfileSyncPanel-[\w-]+\.js$/.test(name));
|
||||
const runtimeConfig = readFileSync(resolve(process.cwd(), 'dist/app-config.js'), 'utf8');
|
||||
const safeRuntimeTemplate = readFileSync(resolve(process.cwd(), 'public/app-config.example.js'), 'utf8');
|
||||
const builtIndex = readFileSync(resolve(process.cwd(), 'dist/index.html'), 'utf8');
|
||||
const builtSemiPrototype = readFileSync(resolve(process.cwd(), 'dist/semi-prototype.html'), 'utf8');
|
||||
const releaseManifest = readFileSync(resolve(process.cwd(), 'dist/.release-assets'), 'utf8').split(/\r?\n/).filter(Boolean);
|
||||
|
||||
if (excelAssets.length !== 1) {
|
||||
@@ -20,6 +23,9 @@ if (mileageWorkers.length !== 1) {
|
||||
if (monitorAssets.length !== 1) {
|
||||
throw new Error(`production build must contain exactly one monitor page asset, found ${monitorAssets.length}: ${monitorAssets.join(', ') || 'none'}`);
|
||||
}
|
||||
if (vehicleAssets.length !== 1 || profileSyncAssets.length !== 1) {
|
||||
throw new Error(`vehicle profile sync must remain one deferred route asset: vehicle=${vehicleAssets.join(', ') || 'none'} sync=${profileSyncAssets.join(', ') || 'none'}`);
|
||||
}
|
||||
if (runtimeConfig !== safeRuntimeTemplate) {
|
||||
throw new Error('production dist/app-config.js must match the credential-free runtime template');
|
||||
}
|
||||
@@ -33,6 +39,12 @@ if (!mainAsset || !assets.includes(mainAsset)
|
||||
|| !readFileSync(resolve(assetsDirectory, mainAsset), 'utf8').includes('vehicle-platform:ready')) {
|
||||
throw new Error('production entry must retain the React boot-ready handshake');
|
||||
}
|
||||
const semiPrototypeAsset = builtSemiPrototype.match(/<script[^>]+type="module"[^>]+src="\/assets\/([^"/]+\.js)"/)?.[1];
|
||||
if (!builtSemiPrototype.includes('Semi UI 原型 · 羚牛车辆数据中台')
|
||||
|| !semiPrototypeAsset
|
||||
|| !assets.includes(semiPrototypeAsset)) {
|
||||
throw new Error('production build must contain the standalone Semi UI prototype entry and asset');
|
||||
}
|
||||
if (releaseManifest.length !== assets.length || releaseManifest.some((name, index) => name !== [...assets].sort()[index])) {
|
||||
throw new Error('production dist/.release-assets must list every generated asset exactly once in sorted order');
|
||||
}
|
||||
@@ -60,5 +72,14 @@ const monitorBytes = statSync(resolve(assetsDirectory, monitorAssets[0])).size;
|
||||
if (monitorBytes > 35_000) {
|
||||
throw new Error(`monitor critical-path asset exceeds 35000 bytes: ${monitorBytes}`);
|
||||
}
|
||||
const vehicleBytes = statSync(resolve(assetsDirectory, vehicleAssets[0])).size;
|
||||
if (vehicleBytes > 30_000) {
|
||||
throw new Error(`vehicle detail critical-path asset exceeds 30000 bytes: ${vehicleBytes}`);
|
||||
}
|
||||
const profileSyncBytes = statSync(resolve(assetsDirectory, profileSyncAssets[0])).size;
|
||||
const vehicleSource = readFileSync(resolve(assetsDirectory, vehicleAssets[0]), 'utf8');
|
||||
if (!vehicleSource.includes(profileSyncAssets[0])) {
|
||||
throw new Error('vehicle profile sync asset must be loaded only through the vehicle page dynamic import');
|
||||
}
|
||||
const qrBytes = statSync(resolve(assetsDirectory, qrAssets[0])).size;
|
||||
process.stdout.write(`web_build_gate=ok release_assets=${releaseManifest.length} exceljs_assets=1 exceljs_bytes=${excelBytes} mileage_workers=1 worker_bytes=${workerBytes} monitor_bytes=${monitorBytes} qr_deferred=1 qr_bytes=${qrBytes} runtime_config_sanitized=1 boot_recovery=1\n`);
|
||||
process.stdout.write(`web_build_gate=ok release_assets=${releaseManifest.length} exceljs_assets=1 exceljs_bytes=${excelBytes} mileage_workers=1 worker_bytes=${workerBytes} monitor_bytes=${monitorBytes} vehicle_bytes=${vehicleBytes} profile_sync_deferred=1 profile_sync_bytes=${profileSyncBytes} qr_deferred=1 qr_bytes=${qrBytes} runtime_config_sanitized=1 boot_recovery=1\n`);
|
||||
|
||||
Reference in New Issue
Block a user