summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/web/boot.js
diff options
context:
space:
mode:
authoranatawa12 <anatawa12@icloud.com>2025-08-08 11:26:18 +0900
committerGitHub <noreply@github.com>2025-08-08 11:26:18 +0900
commit8598f3912ecc16f9b7c3f502e09d9ea96f7e507d (patch)
tree73b24c7ab473189a679ae6aa476b6822f812cbed /packages/backend/src/server/web/boot.js
parentUpdate CONTRIBUTING.md (diff)
downloadmisskey-8598f3912ecc16f9b7c3f502e09d9ea96f7e507d.tar.gz
misskey-8598f3912ecc16f9b7c3f502e09d9ea96f7e507d.tar.bz2
misskey-8598f3912ecc16f9b7c3f502e09d9ea96f7e507d.zip
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})
Diffstat (limited to 'packages/backend/src/server/web/boot.js')
-rw-r--r--packages/backend/src/server/web/boot.js91
1 files changed, 38 insertions, 53 deletions
diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js
index 1a30e9ed2b..0c0b46f82b 100644
--- a/packages/backend/src/server/web/boot.js
+++ b/packages/backend/src/server/web/boot.js
@@ -22,62 +22,31 @@
return;
}
- //#region Detect language & fetch translations
- if (!localStorage.hasOwnProperty('locale')) {
- const supportedLangs = LANGS;
- let lang = localStorage.getItem('lang');
- if (lang == null || !supportedLangs.includes(lang)) {
- if (supportedLangs.includes(navigator.language)) {
- lang = navigator.language;
- } else {
- lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
-
- // Fallback
- if (lang == null) lang = 'en-US';
- }
- }
-
- const metaRes = await window.fetch('/api/meta', {
- method: 'POST',
- body: JSON.stringify({}),
- credentials: 'omit',
- cache: 'no-cache',
- headers: {
- 'Content-Type': 'application/json',
- },
- });
- if (metaRes.status !== 200) {
- renderError('META_FETCH');
- return;
- }
- const meta = await metaRes.json();
- const v = meta.version;
- if (v == null) {
- renderError('META_FETCH_V');
- return;
- }
+ //#region Detect language
+ const supportedLangs = LANGS;
+ /** @type { string } */
+ let lang = localStorage.getItem('lang');
+ if (lang == null || !supportedLangs.includes(lang)) {
+ if (supportedLangs.includes(navigator.language)) {
+ lang = navigator.language;
+ } else {
+ lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
- // for https://github.com/misskey-dev/misskey/issues/10202
- if (lang == null || lang.toString == null || lang.toString() === 'null') {
- console.error('invalid lang value detected!!!', typeof lang, lang);
- lang = 'en-US';
+ // Fallback
+ if (lang == null) lang = 'en-US';
}
+ }
- const localRes = await window.fetch(`/assets/locales/${lang}.${v}.json`);
- if (localRes.status === 200) {
- localStorage.setItem('lang', lang);
- localStorage.setItem('locale', await localRes.text());
- localStorage.setItem('localeVersion', v);
- } else {
- renderError('LOCALE_FETCH');
- return;
- }
+ // for https://github.com/misskey-dev/misskey/issues/10202
+ if (lang == null || lang.toString == null || lang.toString() === 'null') {
+ console.error('invalid lang value detected!!!', typeof lang, lang);
+ lang = 'en-US';
}
//#endregion
//#region Script
async function importAppScript() {
- await import(`/vite/${CLIENT_ENTRY}`)
+ await import(CLIENT_ENTRY ? `/vite/${CLIENT_ENTRY.replace('scripts', lang)}` : '/vite/src/_boot_.ts')
.catch(async e => {
console.error(e);
renderError('APP_IMPORT', e);
@@ -162,9 +131,25 @@
await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve));
}
- const locale = JSON.parse(localStorage.getItem('locale') || '{}');
+ let messages = null;
+ const bootloaderLocales = localStorage.getItem('bootloaderLocales');
+ if (bootloaderLocales) {
+ messages = JSON.parse(bootloaderLocales);
+ }
+ if (!messages) {
+ // older version of misskey does not store bootloaderLocales, stores locale as a whole
+ const legacyLocale = localStorage.getItem('locale');
+ if (legacyLocale) {
+ const parsed = JSON.parse(legacyLocale);
+ messages = {
+ ...(parsed._bootErrors ?? {}),
+ reload: parsed.reload,
+ };
+ }
+ }
+ if (!messages) messages = {};
- const messages = Object.assign({
+ messages = Object.assign({
title: 'Failed to initialize Misskey',
solution: 'The following actions may solve the problem.',
solution1: 'Update your os and browser',
@@ -176,8 +161,8 @@
otherOption2: 'Start the simple client',
otherOption3: 'Start the repair tool',
otherOption4: 'Start Misskey in safe mode',
- }, locale?._bootErrors || {});
- const reload = locale?.reload || 'Reload';
+ reload: 'Reload',
+ }, messages);
const safeModeUrl = new URL(window.location.href);
safeModeUrl.searchParams.set('safemode', 'true');
@@ -193,7 +178,7 @@
</svg>
<h1>${messages.title}</h1>
<button class="button-big" onclick="location.reload(true);">
- <span class="button-label-big">${reload}</span>
+ <span class="button-label-big">${messages?.reload}</span>
</button>
<p><b>${messages.solution}</b></p>
<p>${messages.solution1}</p>