Skip to content

Commit

Permalink
perf: merge all namespace of i18n resource in prod
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Sep 13, 2024
1 parent 304cb7f commit 92bfce0
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 39 deletions.
50 changes: 48 additions & 2 deletions configs/vite.render.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFileSync } from "node:fs"
import { resolve } from "node:path"
import fs, { readFileSync } from "node:fs"
import path, { resolve } from "node:path"

import * as babel from "@babel/core"
import generate from "@babel/generator"
Expand All @@ -14,6 +14,51 @@ import { getGitHash } from "../scripts/lib"

const pkg = JSON.parse(readFileSync("package.json", "utf8"))
const isCI = process.env.CI === "true" || process.env.CI === "1"
function localesPlugin(): Plugin {
return {
name: "locales-merge",
enforce: "post",
generateBundle(options, bundle) {

Check failure on line 21 in configs/vite.render.config.ts

View workflow job for this annotation

GitHub Actions / release (macos-latest)

'options' is declared but its value is never read.

Check failure on line 21 in configs/vite.render.config.ts

View workflow job for this annotation

GitHub Actions / release (ubuntu-latest)

'options' is declared but its value is never read.

Check failure on line 21 in configs/vite.render.config.ts

View workflow job for this annotation

GitHub Actions / release (windows-latest)

'options' is declared but its value is never read.

Check failure on line 21 in configs/vite.render.config.ts

View workflow job for this annotation

GitHub Actions / Lint and Typecheck (18.x)

'options' is declared but its value is never read.
const localesDir = path.resolve(__dirname, "locales")
const namespaces = fs.readdirSync(localesDir)
const languageResources = {}

namespaces.forEach((namespace) => {
const namespacePath = path.join(localesDir, namespace)
const files = fs.readdirSync(namespacePath).filter((file) => file.endsWith(".json"))

files.forEach((file) => {
const lang = path.basename(file, ".json")
const filePath = path.join(namespacePath, file)
const content = JSON.parse(fs.readFileSync(filePath, "utf-8"))

if (!languageResources[lang]) {
languageResources[lang] = {}
}
languageResources[lang][namespace] = content
})
})

Object.entries(languageResources).forEach(([lang, resources]) => {
const fileName = `locales/${lang}.js`
const content = `export default ${JSON.stringify(resources)};`

this.emitFile({
type: "asset",
fileName,
source: content,
})
})

// Remove original JSON chunks
Object.keys(bundle).forEach((key) => {
if (key.startsWith("locales/") && key.endsWith(".json")) {
delete bundle[key]
}
})
},
}
}

export const viteRenderBaseConfig = {
resolve: {
Expand Down Expand Up @@ -52,6 +97,7 @@ export const viteRenderBaseConfig = {
},
}),

localesPlugin(),
viteTwToRawString(),

{
Expand Down
12 changes: 1 addition & 11 deletions src/renderer/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,7 @@ if (import.meta.hot) {
async ({ file, content }: { file: string; content: string }) => {
const resources = JSON.parse(content)
const i18next = jotaiStore.get(i18nAtom)
// `file` is absolute path e.g. /Users/innei/git/follow/locales/en.json
// Absolute path e.g. /Users/innei/git/follow/locales/<module-name>/en.json

// 1. parse root language
// if (!file.includes("locales/namespaces")) {
// const lang = file.split("/").pop()?.replace(".json", "")
// if (!lang) return
// i18next.addResourceBundle(lang, defaultNS, resources, true, true)
// i18next.reloadResources(lang, defaultNS)
// } else {

const nsName = file.match(/locales\/(.+?)\//)?.[1]

if (!nsName) return
Expand All @@ -48,7 +39,6 @@ if (import.meta.hot) {

console.info("reload", lang, nsName)
await i18next.reloadResources(lang, nsName)
// }

import.meta.env.DEV && EventBus.dispatch("I18N_UPDATE", "")
},
Expand Down
46 changes: 22 additions & 24 deletions src/renderer/src/providers/i18n-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,35 @@ const langChangedHandler = async (lang: string) => {

loadingLangLock.add(lang)

const nsGlobbyMap = import.meta.glob("@locales/*/*.json")
if (import.meta.env.DEV) {
const nsGlobbyMap = import.meta.glob("@locales/*/*.json")

// const rootGlobbyMap = import.meta.glob("@locales/*.json")
// const rootResources = await rootGlobbyMap[`../../locales/${lang}.json`]()
// .then((m: any) => m.default)
// .catch(() => {
// toast.error(`${t("common:tips.load-lng-error")}: ${lang}`)
// })
// i18next.addResourceBundle(lang, defaultNS, rootResources, true, true)
const namespaces = Object.keys(defaultResources.en)

const namespaces = Object.keys(defaultResources.en)
const res = await Promise.allSettled(
namespaces.map(async (ns) => {
const loader = nsGlobbyMap[`../../locales/${ns}/${lang}.json`]

const res = await Promise.allSettled(
namespaces.map(async (ns) => {
// if (ns === defaultNS) return
if (!loader) return
const nsResources = await loader().then((m: any) => m.default)

const loader = nsGlobbyMap[`../../locales/${ns}/${lang}.json`]

if (!loader) return
const nsResources = await loader().then((m: any) => m.default)
i18next.addResourceBundle(lang, ns, nsResources, true, true)
}),
)

i18next.addResourceBundle(lang, ns, nsResources, true, true)
}),
)
for (const r of res) {
if (r.status === "rejected") {
toast.error(`${t("common:tips.load-lng-error")}: ${lang}`)
loadingLangLock.delete(lang)

for (const r of res) {
if (r.status === "rejected") {
toast.error(`${t("common:tips.load-lng-error")}: ${lang}`)
loadingLangLock.delete(lang)
return
}
}
} else {
const res = await eval(`import('/locales/${lang}.js').then((res) => res?.default || res)`)

return
for (const namespace in res) {
i18next.addResourceBundle(lang, namespace, res[namespace], true, true)
}
}

Expand Down
3 changes: 1 addition & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default ({ mode }) => {
__debug_proxy: resolve(ROOT, "/__debug_proxy.html"),
},
output: {
experimentalMinChunkSize: 500_000,
// experimentalMinChunkSize: 500_000,
},
},
},
Expand All @@ -97,7 +97,6 @@ export default ({ mode }) => {
}),
htmlPlugin(typedEnv),
mkcert(),

devPrint(),

process.env.ANALYZER && analyzer(),
Expand Down

0 comments on commit 92bfce0

Please sign in to comment.