misskey/packages/frontend/build.ts
anatawa12 8598f3912e
per-locale bundle & inline locale (#16369)
* feat: split entry file by locale name

* chore: とりあえず transform hook で雑に分割

* chore: とりあえず transform 結果をいい感じに

* chore: concurrent buildで高速化

* chore: vite ではローケルのないものをビルドして後処理でどうにかするように

* chore: 後処理のためにi18n.jを単体になるように切り出す

* chore: use typescript

* chore: remove unref(i18n) in vite build process

* chore: inline variable

* fix: build error

* fix: i18n.ts.something.replaceAll() become error

* chore: ignore export specifier from error

* chore: support i18n.tsx as object

* chore: process literal for all files

* chore: split config and locale

* chore: inline locale name

* chore: remove updating locale in boot common

* chore: use top-level await to load locales

* chore: inline locale

* chore: remove loading locale from boot.js

* chore: remove loading locale from boot.js

* コメント追加

* fix test; fetchに失敗する

* import削除ログをdebugレベルに

* fix: watch pug

* chore: use hash for entry files

* chore: remove es-module-lexer from dependencies

* chore: move to frontend-builder

* chore: use inline locale in embed

* chore: refetch json on hot reload

* feat: store localization related to boot.js in backend in bootloaderLocales localstorage

* 応急処置を戻す

* fix spex

* fix `Using i18n identifier "e" directly. Skipping inlining.` warning

* refactor: use scriptsDir parameter

* chore: remove i18n from depmap

* chore: make build crash if errors

* error -> warn few conditions

* use inline object

* update localstorage keys

* remove accessing locale localstorage

* fix: failed to process i18n.tsx.aaa({x:i18n.bbb})
2025-08-08 11:26:18 +09:00

51 lines
1.2 KiB
TypeScript

import * as fs from 'fs/promises';
import url from 'node:url';
import path from 'node:path';
import { execa } from 'execa';
import locales from '../../locales/index.js';
import { LocaleInliner } from '../frontend-builder/locale-inliner.js'
import { createLogger } from '../frontend-builder/logger';
// requires node 21 or later
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
const outputDir = __dirname + '/../../built/_frontend_vite_';
/**
* @return {Promise<void>}
*/
async function viteBuild() {
await execa('vite', ['build'], {
cwd: __dirname,
stdout: process.stdout,
stderr: process.stderr,
});
}
async function buildAllLocale() {
const logger = createLogger()
const inliner = await LocaleInliner.create({
outputDir,
logger,
scriptsDir: 'scripts',
i18nFile: 'src/i18n.ts',
})
await inliner.loadFiles();
inliner.collectsModifications();
await inliner.saveAllLocales(locales);
if (logger.errorCount > 0) {
throw new Error(`Build failed with ${logger.errorCount} errors and ${logger.warningCount} warnings.`);
}
}
async function build() {
await fs.rm(outputDir, { recursive: true, force: true });
await viteBuild();
await buildAllLocale();
}
await build();