reduce js bundle size by loading locales dynamically instead of loading all locales

This commit is contained in:
Athou
2023-05-23 16:24:35 +02:00
parent bc7c50f0f3
commit 4eacd238fa
3 changed files with 122 additions and 177 deletions

View File

@@ -6,15 +6,12 @@
"scripts": {
"dev": "vite --host",
"dev:typescript": "tsc --watch",
"build": "npm run i18n:compile && tsc && vite build",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "vitest",
"test:ci": "vitest run",
"eslint": "eslint --ext=.js,.jsx,.ts,.tsx src",
"i18n": "npm run i18n:extract && npm run i18n:compile",
"i18n:extract": "lingui extract --clean",
"i18n:compile": "lingui compile --typescript",
"postinstall": "npm run i18n:compile"
"i18n:extract": "lingui extract --clean"
},
"dependencies": {
"@emotion/react": "^11.11.0",

View File

@@ -1,113 +1,59 @@
import { i18n, Messages } from "@lingui/core"
import { i18n } from "@lingui/core"
import { useAppSelector } from "app/store"
import dayjs from "dayjs"
import "dayjs/locale/ar"
import "dayjs/locale/ca"
import "dayjs/locale/cs"
import "dayjs/locale/cy"
import "dayjs/locale/da"
import "dayjs/locale/de"
import "dayjs/locale/en"
import "dayjs/locale/es"
import "dayjs/locale/fa"
import "dayjs/locale/fi"
import "dayjs/locale/fr"
import "dayjs/locale/gl"
import "dayjs/locale/hu"
import "dayjs/locale/id"
import "dayjs/locale/it"
import "dayjs/locale/ja"
import "dayjs/locale/ko"
import "dayjs/locale/ms"
import "dayjs/locale/nb"
import "dayjs/locale/nl"
import "dayjs/locale/nn"
import "dayjs/locale/pl"
import "dayjs/locale/pt"
import "dayjs/locale/ru"
import "dayjs/locale/sk"
import "dayjs/locale/sv"
import "dayjs/locale/tr"
import "dayjs/locale/zh"
import { useEffect } from "react"
import { messages as arMessages } from "./locales/ar/messages"
import { messages as caMessages } from "./locales/ca/messages"
import { messages as csMessages } from "./locales/cs/messages"
import { messages as cyMessages } from "./locales/cy/messages"
import { messages as daMessages } from "./locales/da/messages"
import { messages as deMessages } from "./locales/de/messages"
import { messages as enMessages } from "./locales/en/messages"
import { messages as esMessages } from "./locales/es/messages"
import { messages as faMessages } from "./locales/fa/messages"
import { messages as fiMessages } from "./locales/fi/messages"
import { messages as frMessages } from "./locales/fr/messages"
import { messages as glMessages } from "./locales/gl/messages"
import { messages as huMessages } from "./locales/hu/messages"
import { messages as idMessages } from "./locales/id/messages"
import { messages as itMessages } from "./locales/it/messages"
import { messages as jaMessages } from "./locales/ja/messages"
import { messages as koMessages } from "./locales/ko/messages"
import { messages as msMessages } from "./locales/ms/messages"
import { messages as nbMessages } from "./locales/nb/messages"
import { messages as nlMessages } from "./locales/nl/messages"
import { messages as nnMessages } from "./locales/nn/messages"
import { messages as plMessages } from "./locales/pl/messages"
import { messages as ptMessages } from "./locales/pt/messages"
import { messages as ruMessages } from "./locales/ru/messages"
import { messages as skMessages } from "./locales/sk/messages"
import { messages as svMessages } from "./locales/sv/messages"
import { messages as trMessages } from "./locales/tr/messages"
import { messages as zhMessages } from "./locales/zh/messages"
interface Locale {
key: string
label: string
messages: Messages
daysjsImportFn: () => Promise<ILocale>
}
// add an object to the array to add a new locale
// don't forget to also add it to the 'locales' array in .linguirc
export const locales: Locale[] = [
{ key: "ar", messages: arMessages, label: "العربية" },
{ key: "ca", messages: caMessages, label: "Català" },
{ key: "cs", messages: csMessages, label: "Čeština" },
{ key: "cy", messages: cyMessages, label: "Cymraeg" },
{ key: "da", messages: daMessages, label: "Danish" },
{ key: "de", messages: deMessages, label: "Deutsch" },
{ key: "en", messages: enMessages, label: "English" },
{ key: "es", messages: esMessages, label: "Español" },
{ key: "fa", messages: faMessages, label: "فارسی" },
{ key: "fi", messages: fiMessages, label: "Suomi" },
{ key: "fr", messages: frMessages, label: "Français" },
{ key: "gl", messages: glMessages, label: "Galician" },
{ key: "hu", messages: huMessages, label: "Magyar" },
{ key: "id", messages: idMessages, label: "Indonesian" },
{ key: "it", messages: itMessages, label: "Italiano" },
{ key: "ja", messages: jaMessages, label: "日本語" },
{ key: "ko", messages: koMessages, label: "한국어" },
{ key: "ms", messages: msMessages, label: "Bahasa Malaysian" },
{ key: "nb", messages: nbMessages, label: "Norsk (bokmål)" },
{ key: "nl", messages: nlMessages, label: "Nederlands" },
{ key: "nn", messages: nnMessages, label: "Norsk (nynorsk)" },
{ key: "pl", messages: plMessages, label: "Polski" },
{ key: "pt", messages: ptMessages, label: "Português" },
{ key: "ru", messages: ruMessages, label: "Русский" },
{ key: "sk", messages: skMessages, label: "Slovenčina" },
{ key: "sv", messages: svMessages, label: "Svenska" },
{ key: "tr", messages: trMessages, label: "Türkçe" },
{ key: "zh", messages: zhMessages, label: "简体中文" },
{ key: "ar", label: "العربية", daysjsImportFn: () => import("dayjs/locale/ar") },
{ key: "ca", label: "Català", daysjsImportFn: () => import("dayjs/locale/ca") },
{ key: "cs", label: "Čeština", daysjsImportFn: () => import("dayjs/locale/cs") },
{ key: "cy", label: "Cymraeg", daysjsImportFn: () => import("dayjs/locale/cy") },
{ key: "da", label: "Danish", daysjsImportFn: () => import("dayjs/locale/da") },
{ key: "de", label: "Deutsch", daysjsImportFn: () => import("dayjs/locale/de") },
{ key: "en", label: "English", daysjsImportFn: () => import("dayjs/locale/en") },
{ key: "es", label: "Español", daysjsImportFn: () => import("dayjs/locale/es") },
{ key: "fa", label: "فارسی", daysjsImportFn: () => import("dayjs/locale/fa") },
{ key: "fi", label: "Suomi", daysjsImportFn: () => import("dayjs/locale/fi") },
{ key: "fr", label: "Français", daysjsImportFn: () => import("dayjs/locale/fr") },
{ key: "gl", label: "Galician", daysjsImportFn: () => import("dayjs/locale/gl") },
{ key: "hu", label: "Magyar", daysjsImportFn: () => import("dayjs/locale/hu") },
{ key: "id", label: "Indonesian", daysjsImportFn: () => import("dayjs/locale/id") },
{ key: "it", label: "Italiano", daysjsImportFn: () => import("dayjs/locale/it") },
{ key: "ja", label: "日本語", daysjsImportFn: () => import("dayjs/locale/ja") },
{ key: "ko", label: "한국어", daysjsImportFn: () => import("dayjs/locale/ko") },
{ key: "ms", label: "Bahasa Malaysian", daysjsImportFn: () => import("dayjs/locale/ms") },
{ key: "nb", label: "Norsk (bokmål)", daysjsImportFn: () => import("dayjs/locale/nb") },
{ key: "nl", label: "Nederlands", daysjsImportFn: () => import("dayjs/locale/nl") },
{ key: "nn", label: "Norsk (nynorsk)", daysjsImportFn: () => import("dayjs/locale/nn") },
{ key: "pl", label: "Polski", daysjsImportFn: () => import("dayjs/locale/pl") },
{ key: "pt", label: "Português", daysjsImportFn: () => import("dayjs/locale/pt") },
{ key: "ru", label: "Русский", daysjsImportFn: () => import("dayjs/locale/ru") },
{ key: "sk", label: "Slovenčina", daysjsImportFn: () => import("dayjs/locale/sk") },
{ key: "sv", label: "Svenska", daysjsImportFn: () => import("dayjs/locale/sv") },
{ key: "tr", label: "Türkçe", daysjsImportFn: () => import("dayjs/locale/tr") },
{ key: "zh", label: "简体中文", daysjsImportFn: () => import("dayjs/locale/zh") },
]
locales.forEach(l => {
i18n.load({
[l.key]: l.messages,
})
})
function activateLocale(locale: string) {
// lingui
import(`./locales/${locale}/messages.po`).then(data => {
i18n.load(locale, data.messages)
i18n.activate(locale)
dayjs.locale(locale)
})
// dayjs
locales
.find(l => l.key === locale)
?.daysjsImportFn()
.then(() => dayjs.locale(locale))
}
export const useI18n = () => {

View File

@@ -1,3 +1,4 @@
import { lingui } from "@lingui/vite-plugin"
import react from "@vitejs/plugin-react"
import { visualizer } from "rollup-plugin-visualizer"
import { defineConfig } from "vite"
@@ -13,6 +14,7 @@ export default defineConfig({
plugins: ["macros"],
},
}),
lingui(),
eslint(),
tsconfigPaths(),
visualizer(),