feat: WC2026 赛事 seed、生产上线初始化脚本与目录归档
重构 seed 为 WC2026 72 场小组赛与 48 强优胜盘;新增 production 模式仅保留 admin 与赛事示例;提供 prod-init-db 全量重置脚本;管理端 i18n 分包与赛事归档能力。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
32
apps/admin/scripts/report-chunk-sizes.mjs
Normal file
32
apps/admin/scripts/report-chunk-sizes.mjs
Normal file
@@ -0,0 +1,32 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { gzipSync } from 'zlib';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const dist = path.join(__dirname, '../dist/assets');
|
||||
|
||||
if (!fs.existsSync(dist)) {
|
||||
console.error('dist/assets not found — run pnpm build first');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = fs
|
||||
.readdirSync(dist)
|
||||
.filter((f) => f.endsWith('.js'))
|
||||
.map((f) => {
|
||||
const buf = fs.readFileSync(path.join(dist, f));
|
||||
return {
|
||||
file: f,
|
||||
raw: buf.length,
|
||||
gzip: gzipSync(buf).length,
|
||||
};
|
||||
})
|
||||
.sort((a, b) => b.gzip - a.gzip);
|
||||
|
||||
console.log('Admin bundle chunk sizes (gzip):');
|
||||
for (const row of files) {
|
||||
console.log(`${(row.gzip / 1024).toFixed(1)} KB gzip ${(row.raw / 1024).toFixed(1)} KB raw ${row.file}`);
|
||||
}
|
||||
const totalGzip = files.reduce((s, r) => s + r.gzip, 0);
|
||||
console.log(`\nTotal JS (all chunks): ${(totalGzip / 1024).toFixed(1)} KB gzip`);
|
||||
51
apps/admin/scripts/split-i18n.mjs
Normal file
51
apps/admin/scripts/split-i18n.mjs
Normal file
@@ -0,0 +1,51 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const root = path.join(__dirname, '../src/i18n');
|
||||
const am = fs.readFileSync(path.join(root, 'admin-messages.ts'), 'utf8');
|
||||
const ap = fs.readFileSync(path.join(root, 'admin-pages.ts'), 'utf8');
|
||||
|
||||
const zhStart = am.indexOf('const zh:');
|
||||
const enStart = am.indexOf('const en:');
|
||||
const msStart = am.indexOf('const ms:');
|
||||
const exportStart = am.indexOf('export const adminMessages');
|
||||
const header = am.slice(0, zhStart);
|
||||
const zhBody = am.slice(zhStart, enStart).replace(/^const zh/, 'const messages');
|
||||
const enBody = am.slice(enStart, msStart).replace(/^const en/, 'const messages');
|
||||
const msBody = am.slice(msStart, exportStart).replace(/^const ms/, 'const messages');
|
||||
|
||||
const apZhEnd = ap.indexOf('export const adminPagesEn');
|
||||
function toDefaultExport(block, constName) {
|
||||
const body = block
|
||||
.replace(`export const ${constName}`, 'const adminPages')
|
||||
.trimEnd();
|
||||
return `${body}\n\nexport default adminPages;\n`;
|
||||
}
|
||||
const apZh = toDefaultExport(ap.slice(0, apZhEnd), 'adminPagesZh');
|
||||
const apEn = toDefaultExport(ap.slice(apZhEnd), 'adminPagesEn');
|
||||
|
||||
fs.mkdirSync(path.join(root, 'bundles'), { recursive: true });
|
||||
fs.mkdirSync(path.join(root, 'pages'), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, 'pages/zh.ts'), `${apZh.trim()}\n`);
|
||||
fs.writeFileSync(path.join(root, 'pages/en.ts'), `${apEn.trim()}\n`);
|
||||
|
||||
const bundles = [
|
||||
['zh-CN', zhBody, "import adminPages from '../pages/zh';"],
|
||||
['en-US', enBody, "import adminPages from '../pages/en';"],
|
||||
['ms-MY', msBody, "import adminPages from '../admin-pages-ms';"],
|
||||
];
|
||||
|
||||
for (const [loc, body, pagesImport] of bundles) {
|
||||
const content = `${pagesImport}\n${body.replace(/\.\.\.adminPages\w+/g, '...adminPages')}\nexport default { ...messages, ...adminPages };\n`;
|
||||
fs.writeFileSync(path.join(root, 'bundles', `${loc}.ts`), content);
|
||||
}
|
||||
|
||||
const typesOnly = header
|
||||
.replace(/import \{ adminPagesEn, adminPagesZh \} from '\.\/admin-pages';\r?\n/, '')
|
||||
.replace(/import \{ adminPagesMs \} from '\.\/admin-pages-ms';\r?\n/, '')
|
||||
+ `export const adminMessages: Record<AdminLocale, Record<string, string>> = {\n 'zh-CN': {},\n 'en-US': {},\n 'ms-MY': {},\n};\n`;
|
||||
|
||||
fs.writeFileSync(path.join(root, 'admin-messages.ts'), typesOnly);
|
||||
console.log('split i18n ok');
|
||||
Reference in New Issue
Block a user