@bleedingdev/modern-js-plugin-i18n 3.4.0-ultramodern.7 → 3.4.0-ultramodern.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/runtime/core.js
CHANGED
|
@@ -48,16 +48,28 @@ const external_context_js_namespaceObject = require("./context.js");
|
|
|
48
48
|
const external_hooks_js_namespaceObject = require("./hooks.js");
|
|
49
49
|
const index_js_namespaceObject = require("./i18n/index.js");
|
|
50
50
|
const backend_index_js_namespaceObject = require("./i18n/backend/index.js");
|
|
51
|
-
const middleware_js_namespaceObject = require("./i18n/backend/middleware.js");
|
|
52
51
|
const detection_index_js_namespaceObject = require("./i18n/detection/index.js");
|
|
53
|
-
const
|
|
52
|
+
const middleware_js_namespaceObject = require("./i18n/detection/middleware.js");
|
|
54
53
|
const instance_js_namespaceObject = require("./i18n/instance.js");
|
|
55
|
-
const utils_js_namespaceObject = require("./i18n/utils.js");
|
|
56
54
|
const external_utils_js_namespaceObject = require("./utils.js");
|
|
57
55
|
require("./types.js");
|
|
58
56
|
const external_I18nLink_js_namespaceObject = require("./I18nLink.js");
|
|
59
57
|
const external_Link_js_namespaceObject = require("./Link.js");
|
|
60
58
|
const external_localizedPaths_js_namespaceObject = require("./localizedPaths.js");
|
|
59
|
+
let i18nLifecycleHelpersPromise;
|
|
60
|
+
function loadI18nLifecycleHelpers() {
|
|
61
|
+
i18nLifecycleHelpersPromise ??= Promise.all([
|
|
62
|
+
import("./i18n/backend/middleware.js"),
|
|
63
|
+
import("./i18n/utils.js")
|
|
64
|
+
]).then(([backendMiddleware, utils])=>({
|
|
65
|
+
useI18nextBackend: backendMiddleware.useI18nextBackend,
|
|
66
|
+
changeI18nLanguage: utils.changeI18nLanguage,
|
|
67
|
+
ensureLanguageMatch: utils.ensureLanguageMatch,
|
|
68
|
+
initializeI18nInstance: utils.initializeI18nInstance,
|
|
69
|
+
setupClonedInstance: utils.setupClonedInstance
|
|
70
|
+
}));
|
|
71
|
+
return i18nLifecycleHelpersPromise;
|
|
72
|
+
}
|
|
61
73
|
const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
62
74
|
name: '@modern-js/plugin-i18n',
|
|
63
75
|
setup: (api)=>{
|
|
@@ -71,6 +83,7 @@ const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
|
71
83
|
return loadReactI18nextIntegration?.() ?? null;
|
|
72
84
|
};
|
|
73
85
|
api.onBeforeRender(async (context)=>{
|
|
86
|
+
const { useI18nextBackend, changeI18nLanguage, ensureLanguageMatch, initializeI18nInstance, setupClonedInstance } = await loadI18nLifecycleHelpers();
|
|
74
87
|
let i18nInstance = await (0, index_js_namespaceObject.getI18nInstance)(userI18nInstance);
|
|
75
88
|
const { i18n: otherConfig } = api.getRuntimeConfig();
|
|
76
89
|
const { initOptions: otherInitOptions } = otherConfig || {};
|
|
@@ -79,11 +92,11 @@ const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
|
79
92
|
I18nextProvider = reactI18nextIntegration?.I18nextProvider ?? null;
|
|
80
93
|
if (reactI18nextIntegration?.initReactI18next) i18nInstance.use(reactI18nextIntegration.initReactI18next);
|
|
81
94
|
const pathname = (0, external_utils_js_namespaceObject.getPathname)(context);
|
|
82
|
-
if (i18nextDetector) (0,
|
|
95
|
+
if (i18nextDetector) (0, middleware_js_namespaceObject.useI18nextLanguageDetector)(i18nInstance);
|
|
83
96
|
const mergedDetection = (0, detection_index_js_namespaceObject.mergeDetectionOptions)(i18nextDetector, detection, localePathRedirect, userInitOptions);
|
|
84
97
|
const mergedBackend = (0, backend_index_js_namespaceObject.mergeBackendOptions)(backend, userInitOptions);
|
|
85
98
|
const hasSdkConfig = 'function' == typeof userInitOptions?.backend?.sdk || mergedBackend?.sdk && 'function' == typeof mergedBackend.sdk;
|
|
86
|
-
if (mergedBackend && (backendEnabled || hasSdkConfig))
|
|
99
|
+
if (mergedBackend && (backendEnabled || hasSdkConfig)) useI18nextBackend(i18nInstance, mergedBackend);
|
|
87
100
|
const { finalLanguage } = await (0, detection_index_js_namespaceObject.detectLanguageWithPriority)(i18nInstance, {
|
|
88
101
|
languages,
|
|
89
102
|
fallbackLanguage,
|
|
@@ -95,17 +108,17 @@ const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
|
95
108
|
pathname,
|
|
96
109
|
ssrContext: context.ssrContext
|
|
97
110
|
});
|
|
98
|
-
await
|
|
111
|
+
await initializeI18nInstance(i18nInstance, finalLanguage, fallbackLanguage, languages, mergedDetection, mergedBackend, userInitOptions);
|
|
99
112
|
if (!(0, runtime_namespaceObject.isBrowser)() && i18nInstance.cloneInstance) {
|
|
100
113
|
i18nInstance = i18nInstance.cloneInstance();
|
|
101
|
-
await
|
|
114
|
+
await setupClonedInstance(i18nInstance, finalLanguage, fallbackLanguage, languages, backendEnabled, backend, i18nextDetector, detection, localePathRedirect, userInitOptions);
|
|
102
115
|
}
|
|
103
|
-
if (localePathRedirect) await
|
|
116
|
+
if (localePathRedirect) await ensureLanguageMatch(i18nInstance, finalLanguage);
|
|
104
117
|
if (!(0, runtime_namespaceObject.isBrowser)()) (0, detection_index_js_namespaceObject.exportServerLngToWindow)(context, finalLanguage);
|
|
105
118
|
context.i18nInstance = i18nInstance;
|
|
106
119
|
latestI18nInstance = i18nInstance;
|
|
107
120
|
context.changeLanguage = async (newLang)=>{
|
|
108
|
-
await
|
|
121
|
+
await changeI18nLanguage(i18nInstance, newLang, {
|
|
109
122
|
detectionOptions: mergedDetection
|
|
110
123
|
});
|
|
111
124
|
};
|
|
@@ -7,13 +7,25 @@ import { ModernI18nProvider, useModernI18n } from "./context.mjs";
|
|
|
7
7
|
import { createContextValue, useClientSideRedirect, useLanguageSync, useSdkResourcesLoader } from "./hooks.mjs";
|
|
8
8
|
import { getI18nInstance } from "./i18n/index.mjs";
|
|
9
9
|
import { mergeBackendOptions } from "./i18n/backend/index.mjs";
|
|
10
|
-
import { useI18nextBackend } from "./i18n/backend/middleware.mjs";
|
|
11
10
|
import { detectLanguageWithPriority, exportServerLngToWindow, mergeDetectionOptions } from "./i18n/detection/index.mjs";
|
|
12
11
|
import { useI18nextLanguageDetector } from "./i18n/detection/middleware.mjs";
|
|
13
12
|
import { getI18nextInstanceForProvider } from "./i18n/instance.mjs";
|
|
14
|
-
import { changeI18nLanguage, ensureLanguageMatch, initializeI18nInstance, setupClonedInstance } from "./i18n/utils.mjs";
|
|
15
13
|
import { buildLocalizedUrl, getPathname, splitUrlTarget } from "./utils.mjs";
|
|
16
14
|
import "./types.mjs";
|
|
15
|
+
let i18nLifecycleHelpersPromise;
|
|
16
|
+
function loadI18nLifecycleHelpers() {
|
|
17
|
+
i18nLifecycleHelpersPromise ??= Promise.all([
|
|
18
|
+
import("./i18n/backend/middleware.mjs"),
|
|
19
|
+
import("./i18n/utils.mjs")
|
|
20
|
+
]).then(([backendMiddleware, utils])=>({
|
|
21
|
+
useI18nextBackend: backendMiddleware.useI18nextBackend,
|
|
22
|
+
changeI18nLanguage: utils.changeI18nLanguage,
|
|
23
|
+
ensureLanguageMatch: utils.ensureLanguageMatch,
|
|
24
|
+
initializeI18nInstance: utils.initializeI18nInstance,
|
|
25
|
+
setupClonedInstance: utils.setupClonedInstance
|
|
26
|
+
}));
|
|
27
|
+
return i18nLifecycleHelpersPromise;
|
|
28
|
+
}
|
|
17
29
|
const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
18
30
|
name: '@modern-js/plugin-i18n',
|
|
19
31
|
setup: (api)=>{
|
|
@@ -27,6 +39,7 @@ const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
|
27
39
|
return loadReactI18nextIntegration?.() ?? null;
|
|
28
40
|
};
|
|
29
41
|
api.onBeforeRender(async (context)=>{
|
|
42
|
+
const { useI18nextBackend, changeI18nLanguage, ensureLanguageMatch, initializeI18nInstance, setupClonedInstance } = await loadI18nLifecycleHelpers();
|
|
30
43
|
let i18nInstance = await getI18nInstance(userI18nInstance);
|
|
31
44
|
const { i18n: otherConfig } = api.getRuntimeConfig();
|
|
32
45
|
const { initOptions: otherInitOptions } = otherConfig || {};
|
|
@@ -8,13 +8,25 @@ import { ModernI18nProvider, useModernI18n } from "./context.mjs";
|
|
|
8
8
|
import { createContextValue, useClientSideRedirect, useLanguageSync, useSdkResourcesLoader } from "./hooks.mjs";
|
|
9
9
|
import { getI18nInstance } from "./i18n/index.mjs";
|
|
10
10
|
import { mergeBackendOptions } from "./i18n/backend/index.mjs";
|
|
11
|
-
import { useI18nextBackend } from "./i18n/backend/middleware.mjs";
|
|
12
11
|
import { detectLanguageWithPriority, exportServerLngToWindow, mergeDetectionOptions } from "./i18n/detection/index.mjs";
|
|
13
12
|
import { useI18nextLanguageDetector } from "./i18n/detection/middleware.mjs";
|
|
14
13
|
import { getI18nextInstanceForProvider } from "./i18n/instance.mjs";
|
|
15
|
-
import { changeI18nLanguage, ensureLanguageMatch, initializeI18nInstance, setupClonedInstance } from "./i18n/utils.mjs";
|
|
16
14
|
import { buildLocalizedUrl, getPathname, splitUrlTarget } from "./utils.mjs";
|
|
17
15
|
import "./types.mjs";
|
|
16
|
+
let i18nLifecycleHelpersPromise;
|
|
17
|
+
function loadI18nLifecycleHelpers() {
|
|
18
|
+
i18nLifecycleHelpersPromise ??= Promise.all([
|
|
19
|
+
import("./i18n/backend/middleware.mjs"),
|
|
20
|
+
import("./i18n/utils.mjs")
|
|
21
|
+
]).then(([backendMiddleware, utils])=>({
|
|
22
|
+
useI18nextBackend: backendMiddleware.useI18nextBackend,
|
|
23
|
+
changeI18nLanguage: utils.changeI18nLanguage,
|
|
24
|
+
ensureLanguageMatch: utils.ensureLanguageMatch,
|
|
25
|
+
initializeI18nInstance: utils.initializeI18nInstance,
|
|
26
|
+
setupClonedInstance: utils.setupClonedInstance
|
|
27
|
+
}));
|
|
28
|
+
return i18nLifecycleHelpersPromise;
|
|
29
|
+
}
|
|
18
30
|
const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
19
31
|
name: '@modern-js/plugin-i18n',
|
|
20
32
|
setup: (api)=>{
|
|
@@ -28,6 +40,7 @@ const createI18nPlugin = (loadReactI18nextIntegration)=>(options)=>({
|
|
|
28
40
|
return loadReactI18nextIntegration?.() ?? null;
|
|
29
41
|
};
|
|
30
42
|
api.onBeforeRender(async (context)=>{
|
|
43
|
+
const { useI18nextBackend, changeI18nLanguage, ensureLanguageMatch, initializeI18nInstance, setupClonedInstance } = await loadI18nLifecycleHelpers();
|
|
31
44
|
let i18nInstance = await getI18nInstance(userI18nInstance);
|
|
32
45
|
const { i18n: otherConfig } = api.getRuntimeConfig();
|
|
33
46
|
const { initOptions: otherInitOptions } = otherConfig || {};
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.4.0-ultramodern.
|
|
20
|
+
"version": "3.4.0-ultramodern.9",
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
@@ -97,15 +97,15 @@
|
|
|
97
97
|
"i18next-fs-backend": "^2.6.6",
|
|
98
98
|
"i18next-http-backend": "^4.0.0",
|
|
99
99
|
"i18next-http-middleware": "^3.9.7",
|
|
100
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.4.0-ultramodern.
|
|
101
|
-
"@modern-js/
|
|
102
|
-
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.4.0-ultramodern.
|
|
103
|
-
"@modern-js/
|
|
104
|
-
"@modern-js/
|
|
105
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.
|
|
100
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.4.0-ultramodern.9",
|
|
101
|
+
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.4.0-ultramodern.9",
|
|
102
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.4.0-ultramodern.9",
|
|
103
|
+
"@modern-js/server-runtime": "npm:@bleedingdev/modern-js-server-runtime@3.4.0-ultramodern.9",
|
|
104
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.9",
|
|
105
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.9"
|
|
106
106
|
},
|
|
107
107
|
"peerDependencies": {
|
|
108
|
-
"@modern-js/runtime": "3.4.0-ultramodern.
|
|
108
|
+
"@modern-js/runtime": "3.4.0-ultramodern.9",
|
|
109
109
|
"i18next": ">=26.3.1",
|
|
110
110
|
"react": "^19.2.7",
|
|
111
111
|
"react-dom": "^19.2.7",
|
|
@@ -129,8 +129,8 @@
|
|
|
129
129
|
"react-i18next": "17.0.8",
|
|
130
130
|
"ts-node": "^10.9.2",
|
|
131
131
|
"typescript": "^6.0.3",
|
|
132
|
-
"@modern-js/
|
|
133
|
-
"@modern-js/
|
|
132
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.4.0-ultramodern.9",
|
|
133
|
+
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.4.0-ultramodern.9"
|
|
134
134
|
},
|
|
135
135
|
"sideEffects": false,
|
|
136
136
|
"publishConfig": {
|
package/src/runtime/core.tsx
CHANGED
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
import type { I18nInitOptions, I18nInstance } from './i18n';
|
|
23
23
|
import { getI18nInstance } from './i18n';
|
|
24
24
|
import { mergeBackendOptions } from './i18n/backend';
|
|
25
|
-
import { useI18nextBackend } from './i18n/backend/middleware';
|
|
26
25
|
import {
|
|
27
26
|
detectLanguageWithPriority,
|
|
28
27
|
exportServerLngToWindow,
|
|
@@ -30,18 +29,37 @@ import {
|
|
|
30
29
|
} from './i18n/detection';
|
|
31
30
|
import { useI18nextLanguageDetector } from './i18n/detection/middleware';
|
|
32
31
|
import { getI18nextInstanceForProvider } from './i18n/instance';
|
|
33
|
-
import {
|
|
34
|
-
changeI18nLanguage,
|
|
35
|
-
ensureLanguageMatch,
|
|
36
|
-
initializeI18nInstance,
|
|
37
|
-
setupClonedInstance,
|
|
38
|
-
} from './i18n/utils';
|
|
39
32
|
import { getPathname } from './utils';
|
|
40
33
|
import './types';
|
|
41
34
|
|
|
42
35
|
export type { I18nSdkLoader, I18nSdkLoadOptions } from '../shared/type';
|
|
43
36
|
export type { Resources } from './i18n/instance';
|
|
44
37
|
|
|
38
|
+
type I18nLifecycleHelpers = {
|
|
39
|
+
useI18nextBackend: typeof import('./i18n/backend/middleware')['useI18nextBackend'];
|
|
40
|
+
changeI18nLanguage: typeof import('./i18n/utils')['changeI18nLanguage'];
|
|
41
|
+
ensureLanguageMatch: typeof import('./i18n/utils')['ensureLanguageMatch'];
|
|
42
|
+
initializeI18nInstance: typeof import('./i18n/utils')['initializeI18nInstance'];
|
|
43
|
+
setupClonedInstance: typeof import('./i18n/utils')['setupClonedInstance'];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
let i18nLifecycleHelpersPromise: Promise<I18nLifecycleHelpers> | undefined;
|
|
47
|
+
|
|
48
|
+
function loadI18nLifecycleHelpers(): Promise<I18nLifecycleHelpers> {
|
|
49
|
+
i18nLifecycleHelpersPromise ??= Promise.all([
|
|
50
|
+
import('./i18n/backend/middleware'),
|
|
51
|
+
import('./i18n/utils'),
|
|
52
|
+
]).then(([backendMiddleware, utils]) => ({
|
|
53
|
+
useI18nextBackend: backendMiddleware.useI18nextBackend,
|
|
54
|
+
changeI18nLanguage: utils.changeI18nLanguage,
|
|
55
|
+
ensureLanguageMatch: utils.ensureLanguageMatch,
|
|
56
|
+
initializeI18nInstance: utils.initializeI18nInstance,
|
|
57
|
+
setupClonedInstance: utils.setupClonedInstance,
|
|
58
|
+
}));
|
|
59
|
+
|
|
60
|
+
return i18nLifecycleHelpersPromise;
|
|
61
|
+
}
|
|
62
|
+
|
|
45
63
|
export interface I18nPluginOptions {
|
|
46
64
|
entryName?: string;
|
|
47
65
|
localeDetection?: BaseLocaleDetectionOptions;
|
|
@@ -104,6 +122,13 @@ export const createI18nPlugin =
|
|
|
104
122
|
};
|
|
105
123
|
|
|
106
124
|
api.onBeforeRender(async context => {
|
|
125
|
+
const {
|
|
126
|
+
useI18nextBackend,
|
|
127
|
+
changeI18nLanguage,
|
|
128
|
+
ensureLanguageMatch,
|
|
129
|
+
initializeI18nInstance,
|
|
130
|
+
setupClonedInstance,
|
|
131
|
+
} = await loadI18nLifecycleHelpers();
|
|
107
132
|
let i18nInstance = await getI18nInstance(userI18nInstance);
|
|
108
133
|
const { i18n: otherConfig } = api.getRuntimeConfig();
|
|
109
134
|
const { initOptions: otherInitOptions } = otherConfig || {};
|
|
@@ -19,6 +19,15 @@ describe('react-i18next runtime boundary', () => {
|
|
|
19
19
|
expect(core).not.toContain("import('react-i18next')");
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
+
test('keeps the runtime plugin factory entry synchronous for federation', () => {
|
|
23
|
+
const core = readRuntimeSource('core.tsx');
|
|
24
|
+
|
|
25
|
+
expect(core).not.toContain("from './i18n/backend/middleware'");
|
|
26
|
+
expect(core).not.toContain("from './i18n/utils'");
|
|
27
|
+
expect(core).toContain("import('./i18n/backend/middleware')");
|
|
28
|
+
expect(core).toContain("import('./i18n/utils')");
|
|
29
|
+
});
|
|
30
|
+
|
|
22
31
|
test('keeps the default runtime entry wired to react-i18next integration', () => {
|
|
23
32
|
const defaultEntry = readRuntimeSource('index.tsx');
|
|
24
33
|
|