forked from Archives/Athou_commafeed
reduce js bundle size by loading locales dynamically instead of loading all locales
This commit is contained in:
@@ -1,84 +1,81 @@
|
||||
{
|
||||
"name": "commafeed-client",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"dev:typescript": "tsc --watch",
|
||||
"build": "npm run i18n:compile && 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"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.0",
|
||||
"@fontsource/open-sans": "^4.5.14",
|
||||
"@lingui/core": "^4.0.0",
|
||||
"@lingui/macro": "^4.0.0",
|
||||
"@lingui/react": "^4.0.0",
|
||||
"@mantine/core": "^6.0.10",
|
||||
"@mantine/form": "^6.0.10",
|
||||
"@mantine/hooks": "^6.0.10",
|
||||
"@mantine/modals": "^6.0.10",
|
||||
"@mantine/notifications": "^6.0.10",
|
||||
"@mantine/spotlight": "^6.0.10",
|
||||
"@mantine/styles": "^6.0.10",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"axios": "^1.4.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"interweave": "^13.1.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"react": "^18.2.0",
|
||||
"react-async-hook": "^4.0.0",
|
||||
"react-contexify": "^6.0.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-ga4": "^2.1.0",
|
||||
"react-icons": "^4.8.0",
|
||||
"react-infinite-scroller": "^1.2.6",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.11.1",
|
||||
"react-swipeable": "^7.0.0",
|
||||
"swagger-ui-react": "^4.18.3",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"tinycon": "^0.6.8",
|
||||
"use-local-storage": "^3.0.0",
|
||||
"websocket-heartbeat-js": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lingui/cli": "^4.0.0",
|
||||
"@lingui/vite-plugin": "^4.0.0",
|
||||
"@types/eslint": "^8.37.0",
|
||||
"@types/mousetrap": "^1.6.11",
|
||||
"@types/react": "^18.2.6",
|
||||
"@types/react-dom": "^18.2.4",
|
||||
"@types/react-infinite-scroller": "^1.2.3",
|
||||
"@types/swagger-ui-react": "^4.18.0",
|
||||
"@types/throttle-debounce": "^5.0.0",
|
||||
"@types/tinycon": "^0.6.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.2",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"eslint": "^8.40.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-plugin-hooks": "^0.4.3",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"prettier": "^2.8.8",
|
||||
"rollup-plugin-visualizer": "^5.9.0",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.5",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-tsconfig-paths": "^4.2.0",
|
||||
"vitest": "^0.31.0",
|
||||
"vitest-mock-extended": "^1.1.3"
|
||||
}
|
||||
"name": "commafeed-client",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"dev:typescript": "tsc --watch",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest",
|
||||
"test:ci": "vitest run",
|
||||
"eslint": "eslint --ext=.js,.jsx,.ts,.tsx src",
|
||||
"i18n:extract": "lingui extract --clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.0",
|
||||
"@fontsource/open-sans": "^4.5.14",
|
||||
"@lingui/core": "^4.0.0",
|
||||
"@lingui/macro": "^4.0.0",
|
||||
"@lingui/react": "^4.0.0",
|
||||
"@mantine/core": "^6.0.10",
|
||||
"@mantine/form": "^6.0.10",
|
||||
"@mantine/hooks": "^6.0.10",
|
||||
"@mantine/modals": "^6.0.10",
|
||||
"@mantine/notifications": "^6.0.10",
|
||||
"@mantine/spotlight": "^6.0.10",
|
||||
"@mantine/styles": "^6.0.10",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"axios": "^1.4.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"interweave": "^13.1.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"react": "^18.2.0",
|
||||
"react-async-hook": "^4.0.0",
|
||||
"react-contexify": "^6.0.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-ga4": "^2.1.0",
|
||||
"react-icons": "^4.8.0",
|
||||
"react-infinite-scroller": "^1.2.6",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.11.1",
|
||||
"react-swipeable": "^7.0.0",
|
||||
"swagger-ui-react": "^4.18.3",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"tinycon": "^0.6.8",
|
||||
"use-local-storage": "^3.0.0",
|
||||
"websocket-heartbeat-js": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lingui/cli": "^4.0.0",
|
||||
"@lingui/vite-plugin": "^4.0.0",
|
||||
"@types/eslint": "^8.37.0",
|
||||
"@types/mousetrap": "^1.6.11",
|
||||
"@types/react": "^18.2.6",
|
||||
"@types/react-dom": "^18.2.4",
|
||||
"@types/react-infinite-scroller": "^1.2.3",
|
||||
"@types/swagger-ui-react": "^4.18.0",
|
||||
"@types/throttle-debounce": "^5.0.0",
|
||||
"@types/tinycon": "^0.6.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
||||
"@typescript-eslint/parser": "^5.59.2",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"eslint": "^8.40.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-plugin-hooks": "^0.4.3",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"prettier": "^2.8.8",
|
||||
"rollup-plugin-visualizer": "^5.9.0",
|
||||
"typescript": "^5.0.4",
|
||||
"vite": "^4.3.5",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-tsconfig-paths": "^4.2.0",
|
||||
"vitest": "^0.31.0",
|
||||
"vitest-mock-extended": "^1.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
i18n.activate(locale)
|
||||
dayjs.locale(locale)
|
||||
// lingui
|
||||
import(`./locales/${locale}/messages.po`).then(data => {
|
||||
i18n.load(locale, data.messages)
|
||||
i18n.activate(locale)
|
||||
})
|
||||
|
||||
// dayjs
|
||||
locales
|
||||
.find(l => l.key === locale)
|
||||
?.daysjsImportFn()
|
||||
.then(() => dayjs.locale(locale))
|
||||
}
|
||||
|
||||
export const useI18n = () => {
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user