chore(frontend): 開発モード時に言語ファイルの変更を自動で反映するように (#16215)

* chore(frontend): 開発モード時に言語ファイルの変更を自動で反映するように

* fix message

* naming

* SPDX
This commit is contained in:
taichan 2025-06-26 08:26:44 +09:00 committed by GitHub
parent 5626677e86
commit b455e63da7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 59 additions and 2 deletions

View File

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
import path from 'node:path'
import locales from '../../../locales/index.js';
const localesDir = path.resolve(__dirname, '../../../locales')
/**
* webSocketでメッセージを送るViteプラグイン
* @returns {import('vite').Plugin}
*/
export default function pluginWatchLocales() {
return {
name: 'watch-locales',
configureServer(server) {
const localeYmlPaths = Object.keys(locales).map(locale => path.join(localesDir, `${locale}.yml`));
// watcherにパスを追加
server.watcher.add(localeYmlPaths);
server.watcher.on('change', (filePath) => {
if (localeYmlPaths.includes(filePath)) {
server.ws.send({
type: 'custom',
event: 'locale-update',
data: filePath.match(/([^\/]+)\.yml$/)?.[1] || null,
})
}
});
},
};
}

View File

@ -81,8 +81,10 @@ export async function common(createVue: () => Promise<App<Element>>) {
//#region Detect language & fetch translations //#region Detect language & fetch translations
const localeVersion = miLocalStorage.getItem('localeVersion'); const localeVersion = miLocalStorage.getItem('localeVersion');
const localeOutdated = (localeVersion == null || localeVersion !== version || locale == null); const localeOutdated = (localeVersion == null || localeVersion !== version || locale == null);
if (localeOutdated) {
const res = await window.fetch(`/assets/locales/${lang}.${version}.json`); async function fetchAndUpdateLocale({ useCache } = { useCache: true }) {
const fetchOptions: RequestInit | undefined = useCache ? undefined : { cache: 'no-store' };
const res = await window.fetch(`/assets/locales/${lang}.${version}.json`, fetchOptions);
if (res.status === 200) { if (res.status === 200) {
const newLocale = await res.text(); const newLocale = await res.text();
const parsedNewLocale = JSON.parse(newLocale); const parsedNewLocale = JSON.parse(newLocale);
@ -92,6 +94,23 @@ export async function common(createVue: () => Promise<App<Element>>) {
updateI18n(parsedNewLocale); updateI18n(parsedNewLocale);
} }
} }
if (localeOutdated) {
fetchAndUpdateLocale();
}
if (import.meta.hot) {
import.meta.hot.on('locale-update', async (updatedLang: string) => {
console.info(`Locale updated: ${updatedLang}`);
if (updatedLang === lang) {
await new Promise(resolve => {
window.setTimeout(resolve, 500);
});
await fetchAndUpdateLocale({ useCache: false });
window.location.reload();
}
});
}
//#endregion //#endregion
// タッチデバイスでCSSの:hoverを機能させる // タッチデバイスでCSSの:hoverを機能させる

View File

@ -13,6 +13,7 @@ import pluginUnwindCssModuleClassName from './lib/rollup-plugin-unwind-css-modul
import pluginJson5 from './vite.json5.js'; import pluginJson5 from './vite.json5.js';
import pluginCreateSearchIndex from './lib/vite-plugin-create-search-index.js'; import pluginCreateSearchIndex from './lib/vite-plugin-create-search-index.js';
import type { Options as SearchIndexOptions } from './lib/vite-plugin-create-search-index.js'; import type { Options as SearchIndexOptions } from './lib/vite-plugin-create-search-index.js';
import pluginWatchLocales from './lib/vite-plugin-watch-locales.js';
const url = process.env.NODE_ENV === 'development' ? yaml.load(await fsp.readFile('../../.config/default.yml', 'utf-8')).url : null; const url = process.env.NODE_ENV === 'development' ? yaml.load(await fsp.readFile('../../.config/default.yml', 'utf-8')).url : null;
const host = url ? (new URL(url)).hostname : undefined; const host = url ? (new URL(url)).hostname : undefined;
@ -102,6 +103,7 @@ export function getConfig(): UserConfig {
}, },
plugins: [ plugins: [
pluginWatchLocales(),
...searchIndexes.map(options => pluginCreateSearchIndex(options)), ...searchIndexes.map(options => pluginCreateSearchIndex(options)),
pluginVue(), pluginVue(),
pluginUnwindCssModuleClassName(), pluginUnwindCssModuleClassName(),