Skip to content

Commit

Permalink
Merge pull request #973 from 3YOURMIND/load-languages-lazily
Browse files Browse the repository at this point in the history
fix(element-ui): externalize translations
  • Loading branch information
Isokaeder authored Jul 23, 2024
2 parents f9d6e76 + 2d3d100 commit 9747b14
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/kotti-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,5 @@
"style": "./dist/style.css",
"type": "module",
"types": "./dist/index.d.ts",
"version": "6.1.0"
"version": "6.1.1"
}
69 changes: 51 additions & 18 deletions packages/kotti-ui/source/kotti-i18n/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import elementLocale from 'element-ui/lib/locale/index.js'
import elementDe from 'element-ui/lib/locale/lang/de.js'
import elementEn from 'element-ui/lib/locale/lang/en.js'
import elementEs from 'element-ui/lib/locale/lang/es.js'
import elementFr from 'element-ui/lib/locale/lang/fr.js'
import elementJa from 'element-ui/lib/locale/lang/ja.js'
import type { Ref, UnwrapRef } from 'vue'
import { computed, inject, provide, reactive, watch } from 'vue'

Expand Down Expand Up @@ -59,6 +54,37 @@ export const useTranslationNamespace = <NS extends keyof KottiI18n.Messages>(
return computed(() => context.messages[namespace])
}

interface DefaultObject<R extends Record<string, unknown>> {
default: DefaultObject<R> | R
}

/**
* HACK: This function works around a CJS/ESM/EsModule interop issue.
*
* The objects we import at `element-ui/lib/locale/lang/[a-z]{2}.js` are EsModules
* (exports.__esModule = true). Due to current javascript flavour shenanigans,
* the imported object that we need can be found at the root, at the `.default` key,
* or even at the `.default.default` key.
* To mitigate we iterate down the potential default chain until we arrive at the
* right position.
*/
const accessDefaultKey = <R extends Record<string, unknown>>(
obj: DefaultObject<R>,
): R => {
if (!('default' in obj)) return obj

let current: DefaultObject<R> | R = obj

// Practically, this should terminate after at most 2 iterations. Make it 10 for good measure
for (let i = 0; i < 10; i++) {
current = current.default as DefaultObject<R> | R
if (!('default' in current)) {
return current
}
}
throw new Error('accessDefaultKey: could not exhaust nested default keys')
}

/**
* Provides the translation context to child components
*/
Expand Down Expand Up @@ -89,19 +115,26 @@ export const useI18nProvide = ({
*/
watch(
locale,
(newValue) => {
const elementUiTranslations = {
'en-US': elementEn,
'de-DE': elementDe,
'es-ES': elementEs,
'fr-FR': elementFr,
'ja-JP': elementJa,
}[newValue]

if ('default' in elementUiTranslations)
throw new Error('Detected Broken Build')

elementLocale.use(elementUiTranslations)
async (newValue) => {
try {
const elementUiTranslations = await {
/* eslint-disable @typescript-eslint/naming-convention */
'en-US': () => import('element-ui/lib/locale/lang/en.js'),
'de-DE': () => import('element-ui/lib/locale/lang/de.js'),
'es-ES': () => import('element-ui/lib/locale/lang/es.js'),
'fr-FR': () => import('element-ui/lib/locale/lang/fr.js'),
'ja-JP': () => import('element-ui/lib/locale/lang/ja.js'),
/* eslint-enable @typescript-eslint/naming-convention */
}[newValue]()

const resolvedEsModuleInterop = accessDefaultKey(elementUiTranslations)

elementLocale.use(resolvedEsModuleInterop)
} catch (error) {
// eslint-disable-next-line no-console
console.error(error)
throw error
}
},
{ immediate: true, flush: 'post' },
)
Expand Down
2 changes: 1 addition & 1 deletion packages/kotti-ui/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default defineConfig(({ mode }) => {
const external = [
...Object.keys(packageJSON.peerDependencies),
...Object.keys(packageJSON.dependencies),
/.*element-ui\/lib\/date-picker.js.*/,
/.*element-ui.*/,
/.*tippy\.js.*/,
/lodash\/.*/,
/vue\/.*/,
Expand Down

0 comments on commit 9747b14

Please sign in to comment.