From b455e63da75aa71eea00adc9349d7b456664fbcd Mon Sep 17 00:00:00 2001 From: taichan <40626578+tai-cha@users.noreply.github.com> Date: Thu, 26 Jun 2025 08:26:44 +0900 Subject: [PATCH] =?UTF-8?q?chore(frontend):=20=E9=96=8B=E7=99=BA=E3=83=A2?= =?UTF-8?q?=E3=83=BC=E3=83=89=E6=99=82=E3=81=AB=E8=A8=80=E8=AA=9E=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=AE=E5=A4=89=E6=9B=B4=E3=82=92?= =?UTF-8?q?=E8=87=AA=E5=8B=95=E3=81=A7=E5=8F=8D=E6=98=A0=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20(#16215)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(frontend): 開発モード時に言語ファイルの変更を自動で反映するように * fix message * naming * SPDX --- .../frontend/lib/vite-plugin-watch-locales.ts | 36 +++++++++++++++++++ packages/frontend/src/boot/common.ts | 23 ++++++++++-- packages/frontend/vite.config.ts | 2 ++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 packages/frontend/lib/vite-plugin-watch-locales.ts diff --git a/packages/frontend/lib/vite-plugin-watch-locales.ts b/packages/frontend/lib/vite-plugin-watch-locales.ts new file mode 100644 index 0000000000..8e209d27bd --- /dev/null +++ b/packages/frontend/lib/vite-plugin-watch-locales.ts @@ -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, + }) + } + }); + }, + }; +} diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index c8098b6cf8..992bde9bd1 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -81,8 +81,10 @@ export async function common(createVue: () => Promise>) { //#region Detect language & fetch translations const localeVersion = miLocalStorage.getItem('localeVersion'); 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) { const newLocale = await res.text(); const parsedNewLocale = JSON.parse(newLocale); @@ -92,6 +94,23 @@ export async function common(createVue: () => Promise>) { 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 // タッチデバイスでCSSの:hoverを機能させる diff --git a/packages/frontend/vite.config.ts b/packages/frontend/vite.config.ts index b0ccbfb65c..77b5b48a18 100644 --- a/packages/frontend/vite.config.ts +++ b/packages/frontend/vite.config.ts @@ -13,6 +13,7 @@ import pluginUnwindCssModuleClassName from './lib/rollup-plugin-unwind-css-modul import pluginJson5 from './vite.json5.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 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 host = url ? (new URL(url)).hostname : undefined; @@ -102,6 +103,7 @@ export function getConfig(): UserConfig { }, plugins: [ + pluginWatchLocales(), ...searchIndexes.map(options => pluginCreateSearchIndex(options)), pluginVue(), pluginUnwindCssModuleClassName(),