You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.4 KiB
112 lines
3.4 KiB
import { readdirSync, readFileSync, rmSync, statSync } from 'node:fs';
|
|
import { join, resolve } from 'node:path';
|
|
import { gzipSync } from 'node:zlib';
|
|
|
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
import { build } from 'vite';
|
|
|
|
const root = process.cwd();
|
|
const outDir = resolve(root, 'build/.bundle-smoke');
|
|
const virtualId = 'virtual:active-app-smoke';
|
|
const resolvedVirtualId = `\0${virtualId}`;
|
|
const maxGzipKb = Number(process.env.ACTIVE_BUNDLE_GZIP_LIMIT_KB ?? 70);
|
|
|
|
// Aliases mirror `svelte.config.js`. Specific subpaths must come before
|
|
// the parent alias — Vite's resolver matches by prefix.
|
|
const alias = {
|
|
'$active-app/services': resolve(root, 'src/arts/active-app/service-factories'),
|
|
'$active-app/presets': resolve(root, 'src/arts/active-app/presets'),
|
|
'$active-app': resolve(root, 'src/arts/active-app'),
|
|
$adom: resolve(root, 'src/arts/adom'),
|
|
$auth: resolve(root, 'src/arts/auth'),
|
|
$bus: resolve(root, 'src/arts/bus'),
|
|
$cache: resolve(root, 'src/arts/cache'),
|
|
$connection: resolve(root, 'src/arts/connection'),
|
|
$frontend: resolve(root, 'src/arts/frontend'),
|
|
$libs: resolve(root, 'src/libs'),
|
|
$locale: resolve(root, 'src/libs/locale'),
|
|
$reactive: resolve(root, 'src/libs/reactive'),
|
|
$format: resolve(root, 'src/arts/format'),
|
|
$http: resolve(root, 'src/arts/http'),
|
|
$lang: resolve(root, 'src/arts/lang'),
|
|
$logger: resolve(root, 'src/arts/logger'),
|
|
$orca: resolve(root, 'src/arts/orca'),
|
|
$perm: resolve(root, 'src/arts/perm'),
|
|
$prefs: resolve(root, 'src/arts/prefs'),
|
|
$session: resolve(root, 'src/arts/session'),
|
|
$sium: resolve(root, 'src/arts/sium'),
|
|
$storage: resolve(root, 'src/arts/storage'),
|
|
$svrs: resolve(root, 'src/svrs'),
|
|
$timer: resolve(root, 'src/arts/timer')
|
|
};
|
|
|
|
rmSync(outDir, { recursive: true, force: true });
|
|
|
|
await build({
|
|
root,
|
|
configFile: false,
|
|
logLevel: 'silent',
|
|
plugins: [
|
|
svelte({ compilerOptions: { runes: true } }),
|
|
{
|
|
name: 'active-app-smoke-entry',
|
|
resolveId(id) {
|
|
return id === virtualId ? resolvedVirtualId : undefined;
|
|
},
|
|
load(id) {
|
|
if (id !== resolvedVirtualId) return undefined;
|
|
return [
|
|
"import { createActiveApp } from '$active-app/active-app.svelte';",
|
|
"import { LogLevel } from '$logger/types';",
|
|
'const App = createActiveApp({ logger: { level: LogLevel.NONE, transports: [] } });',
|
|
'App.dispose();',
|
|
'export default App;'
|
|
].join('\n');
|
|
}
|
|
}
|
|
],
|
|
resolve: { alias },
|
|
build: {
|
|
emptyOutDir: true,
|
|
minify: 'oxc',
|
|
outDir,
|
|
rollupOptions: {
|
|
input: virtualId,
|
|
output: {
|
|
chunkFileNames: 'chunks/[name]-[hash].js',
|
|
entryFileNames: 'entry.js',
|
|
format: 'es'
|
|
}
|
|
},
|
|
sourcemap: false
|
|
}
|
|
});
|
|
|
|
const jsFiles = listFiles(outDir).filter((file) => file.endsWith('.js'));
|
|
const rawBytes = jsFiles.reduce((sum, file) => sum + statSync(file).size, 0);
|
|
const gzBytes = gzipSync(Buffer.concat(jsFiles.map((file) => readFileSync(file)))).byteLength;
|
|
const rawKb = bytesToKb(rawBytes);
|
|
const gzKb = bytesToKb(gzBytes);
|
|
|
|
console.log(
|
|
`active bundle smoke: ${gzKb.toFixed(2)} KB gzip (${rawKb.toFixed(2)} KB raw, ${jsFiles.length} JS file)`
|
|
);
|
|
|
|
if (gzKb > maxGzipKb) {
|
|
console.error(
|
|
`active bundle smoke exceeded ${maxGzipKb.toFixed(2)} KB gzip. Current: ${gzKb.toFixed(2)} KB.`
|
|
);
|
|
process.exitCode = 1;
|
|
}
|
|
|
|
function listFiles(dir) {
|
|
return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
|
|
const path = join(dir, entry.name);
|
|
return entry.isDirectory() ? listFiles(path) : [path];
|
|
});
|
|
}
|
|
|
|
function bytesToKb(bytes) {
|
|
return bytes / 1024;
|
|
}
|