Skip to content

Commit 7d2fa14

Browse files
committed
fix(hmr): fix i18n hot module replace in browser mode
1 parent 6f26b50 commit 7d2fa14

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/utils/i18n.utils.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ export const useI18n = (...roots: string[]): ReturnType<typeof chromeUseI18n> =>
1010
const store = useI18nStore();
1111
const router = useRouterStore();
1212

13-
if (!store.locales?.[store.lang]) {
13+
if (import.meta.hot) {
14+
console.info('Listening to i18n HMR changes');
15+
import.meta.hot.send('fetch:i18n');
16+
import.meta.hot.on('update:i18n', (data: { lang: string; locale: Locale }[]) => {
17+
data?.forEach(({ lang, locale }) => store.addLocale(locale, lang));
18+
});
19+
} else if (!store.locales?.[store.lang]) {
1420
fetch(new URL(`${router.baseUrl ?? './'}_locales/${store.lang}/messages.json`, new URL(import.meta.url).origin))
1521
.then(r => r.json())
1622
.then((locale: Locale) => store.addLocale(locale))

vite.config.ts

+34
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { readdir, readFile } from 'fs/promises';
12
import { dirname, relative } from 'path';
23
import { fileURLToPath, URL } from 'url';
34

@@ -33,6 +34,8 @@ const getInput = (hmr: boolean, _isWeb: boolean): InputOption => {
3334
return inputs;
3435
};
3536

37+
const i18nRegex = /.*src\/i18n\/([a-zA-Z]+)\/.*\.json/;
38+
3639
const getPlugins = (): PluginOption[] => [
3740
dtsPlugin({
3841
include: ['index.ts', 'web/**'],
@@ -43,6 +46,37 @@ const getPlugins = (): PluginOption[] => [
4346
}),
4447
viteVueCE(),
4548

49+
{
50+
name: 'i18n-hmr',
51+
configureServer: server => {
52+
console.info('server start');
53+
server.ws.on('fetch:i18n', async () => {
54+
const dir = await readdir('dist/_locales');
55+
const locales = dir.map(_lang =>
56+
readFile(`dist/_locales/${_lang}/messages.json`, { encoding: 'utf-8' }).then(locale => ({ lang: _lang, locale: JSON.parse(locale) })),
57+
);
58+
server.ws.send({
59+
type: 'custom',
60+
event: 'update:i18n',
61+
data: await Promise.all(locales),
62+
});
63+
});
64+
},
65+
handleHotUpdate: async ({ server, file, read }) => {
66+
const lang = file.match(i18nRegex)?.[1];
67+
if (lang) {
68+
console.info('Emit new i18n', file);
69+
const locale = JSON.parse(await read());
70+
server.ws.send({
71+
type: 'custom',
72+
event: 'update:i18n',
73+
data: [{ lang, locale }],
74+
});
75+
}
76+
return [];
77+
},
78+
},
79+
4680
// replace document query selector to inject naive-ui within shadow root instead of document head
4781
{
4882
name: 'chunk-transform',

0 commit comments

Comments
 (0)