@common-stack/generate-plugin 6.0.8-alpha.9 → 7.0.2-alpha.0
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/CHANGELOG.md +5 -271
- package/lib/common/package-releases/package.json +26 -0
- package/lib/common/package-releases/package.json.cjs +33 -0
- package/lib/common/package-releases/package.json.cjs.map +1 -0
- package/lib/common/package-releases/package.json.mjs +33 -0
- package/lib/common/package-releases/package.json.mjs.map +1 -0
- package/lib/generators/add-backend/files/Dockerfile +2 -0
- package/lib/generators/add-backend/files/package.json +4 -2
- package/lib/generators/add-backend/files/webpack.config.js +3 -1
- package/lib/generators/add-frontend/frameworks/antui/src/context.tsx.template +8 -0
- package/lib/generators/add-frontend/frameworks/antui/{entry.client.tsx.template → src/entry.client.tsx.template} +12 -12
- package/{src/generators/add-frontend/frameworks/antui → lib/generators/add-frontend/frameworks/antui/src}/entry.server.tsx.template +61 -51
- package/{src/generators/add-frontend/frameworks/antui → lib/generators/add-frontend/frameworks/antui/src}/root.tsx.template +6 -15
- package/lib/generators/add-frontend/frameworks/chakraui/{context.tsx.template → src/context.tsx.template} +6 -0
- package/lib/generators/add-frontend/frameworks/chakraui/{entry.client.tsx.template → src/entry.client.tsx.template} +21 -18
- package/{src/generators/add-frontend/frameworks/chakraui → lib/generators/add-frontend/frameworks/chakraui/src}/entry.server.tsx.template +33 -30
- package/lib/generators/add-frontend/frameworks/chakraui/{root.tsx.template → src/root.tsx.template} +8 -4
- package/{src/generators/add-frontend/frameworks/tailwindui → lib/generators/add-frontend/frameworks/tailwindui/src}/entry.client.tsx.template +3 -10
- package/lib/generators/add-frontend/generator.cjs +83 -36
- package/lib/generators/add-frontend/generator.cjs.map +1 -1
- package/lib/generators/add-frontend/generator.mjs +83 -36
- package/lib/generators/add-frontend/generator.mjs.map +1 -1
- package/lib/generators/add-frontend/templates/Dockerfile +4 -0
- package/lib/generators/add-frontend/templates/package.json +7 -3
- package/lib/generators/add-frontend/templates/vite.config.ts.template +18 -1
- package/lib/generators/add-fullstack/files/Jenkinsfile +2 -2
- package/lib/generators/add-fullstack/files/cdecode-config.json +126 -0
- package/lib/generators/add-fullstack/files/package.json +31 -18
- package/lib/generators/add-fullstack/files/rollup.config.base.mjs +17 -95
- package/lib/generators/add-fullstack/files/tools/codegenGenerator.mjs +36 -0
- package/lib/generators/add-fullstack/generator.cjs +8 -4
- package/lib/generators/add-fullstack/generator.cjs.map +1 -1
- package/lib/generators/add-fullstack/generator.mjs +8 -4
- package/lib/generators/add-fullstack/generator.mjs.map +1 -1
- package/lib/generators/add-fullstack/schema.json +1 -1
- package/lib/generators/add-moleculer/files/Dockerfile +2 -0
- package/lib/generators/add-moleculer/files/config.json +5 -0
- package/lib/generators/add-moleculer/files/package.json +10 -6
- package/lib/generators/add-moleculer/files/rollup.config.mjs +14 -1
- package/package.json +4 -3
- package/rollup.config.mjs +3 -0
- package/src/common/package-releases/package.json +26 -0
- package/src/generators/add-frontend/__snapshots__/generator.test.ts.snap +33 -0
- package/src/generators/add-frontend/frameworks/antui/src/context.tsx.template +8 -0
- package/src/generators/add-frontend/frameworks/antui/{entry.client.tsx.template → src/entry.client.tsx.template} +12 -12
- package/{lib/generators/add-frontend/frameworks/antui → src/generators/add-frontend/frameworks/antui/src}/entry.server.tsx.template +61 -51
- package/{lib/generators/add-frontend/frameworks/antui → src/generators/add-frontend/frameworks/antui/src}/root.tsx.template +6 -15
- package/src/generators/add-frontend/frameworks/chakraui/{context.tsx.template → src/context.tsx.template} +6 -0
- package/src/generators/add-frontend/frameworks/chakraui/{entry.client.tsx.template → src/entry.client.tsx.template} +21 -18
- package/{lib/generators/add-frontend/frameworks/chakraui → src/generators/add-frontend/frameworks/chakraui/src}/entry.server.tsx.template +33 -30
- package/src/generators/add-frontend/frameworks/chakraui/{root.tsx.template → src/root.tsx.template} +8 -4
- package/src/generators/add-frontend/frameworks/tailwindui/postcss.config.js +6 -0
- package/{lib/generators/add-frontend/frameworks/tailwindui → src/generators/add-frontend/frameworks/tailwindui/src}/entry.client.tsx.template +3 -10
- package/src/generators/add-frontend/frameworks/tailwindui/tailwind.config.ts.template +12 -0
- package/src/generators/add-frontend/generator.test.ts +79 -0
- package/src/generators/add-frontend/generator.ts +109 -44
- package/src/generators/add-fullstack/files/Jenkinsfile +2 -2
- package/src/generators/add-fullstack/files/cdecode-config.json +126 -0
- package/src/generators/add-fullstack/files/package.json +32 -19
- package/src/generators/add-fullstack/files/rollup.config.base.mjs +17 -95
- package/src/generators/add-fullstack/files/tools/codegenGenerator.mjs +36 -0
- package/src/generators/add-fullstack/generator.ts +8 -4
- package/src/generators/add-fullstack/schema.json +1 -1
- package/src/generators/add-moleculer/files/.dockerignore +2 -1
- package/src/generators/add-moleculer/files/CHANGELOG.md +0 -4
- package/src/generators/add-moleculer/files/Dockerfile +2 -0
- package/src/generators/add-moleculer/files/config.json +5 -0
- package/src/generators/add-moleculer/files/package.json +11 -7
- package/src/generators/add-moleculer/files/rollup.config.mjs +14 -1
- package/tsconfig.spec.json +9 -0
- package/docker-releases/backend/package.json +0 -134
- package/docker-releases/frontend/antd/package.json +0 -121
- package/lib/generators/add-fullstack/files/codegen.yml +0 -47
- package/lib/generators/add-moleculer/files/src/modules/module.ts.template +0 -31
- package/src/generators/add-frontend/generator.spec.ts +0 -20
- package/src/generators/add-fullstack/files/codegen.yml +0 -47
- package/src/generators/add-moleculer/files/src/modules/module.ts.template +0 -31
- /package/lib/generators/add-frontend/{templates → frameworks/tailwindui}/postcss.config.js +0 -0
- /package/lib/generators/add-frontend/frameworks/tailwindui/{entry.server.tsx.template → src/entry.server.tsx.template} +0 -0
- /package/lib/generators/add-frontend/frameworks/tailwindui/{root.tsx.template → src/root.tsx.template} +0 -0
- /package/lib/generators/add-frontend/frameworks/tailwindui/{tailwind.css → src/tailwind.css} +0 -0
- /package/lib/generators/add-frontend/{templates → frameworks/tailwindui}/tailwind.config.ts.template +0 -0
- /package/lib/generators/add-frontend/{generator.spec.d.ts → generator.test.d.ts} +0 -0
- /package/src/generators/add-frontend/frameworks/tailwindui/{entry.server.tsx.template → src/entry.server.tsx.template} +0 -0
- /package/src/generators/add-frontend/frameworks/tailwindui/{root.tsx.template → src/root.tsx.template} +0 -0
- /package/src/generators/add-frontend/frameworks/tailwindui/{tailwind.css → src/tailwind.css} +0 -0
|
@@ -27,10 +27,14 @@ import Backend from 'i18next-fs-backend';
|
|
|
27
27
|
import { resolve } from 'node:path';
|
|
28
28
|
// @ts-ignore
|
|
29
29
|
import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
|
|
30
|
+
// @ts-ignore
|
|
30
31
|
import config from '@app/cde-webconfig.json';
|
|
31
32
|
// @ts-ignore
|
|
32
33
|
import createEmotionCache from '@app/frontend-stack-react/entries/common/createEmotionCache';
|
|
33
34
|
import type { IAppLoadContext } from '@common-stack/client-core';
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
import publicEnv from '@src/config/public-config';
|
|
37
|
+
import { LocaleContext } from './context';
|
|
34
38
|
|
|
35
39
|
const ABORT_DELAY = 5_000;
|
|
36
40
|
const antdCache = createAntdCache();
|
|
@@ -41,18 +45,23 @@ class ConstantsTransform extends Transform {
|
|
|
41
45
|
_apolloState: any;
|
|
42
46
|
_reduxState: any;
|
|
43
47
|
_styleSheet: string;
|
|
48
|
+
_lng: string;
|
|
44
49
|
|
|
45
|
-
constructor(fills: string[], apolloState: any, reduxState: any, styleSheet: any) {
|
|
50
|
+
constructor(fills: string[], apolloState: any, reduxState: any, styleSheet: any, lng: string) {
|
|
46
51
|
super();
|
|
47
52
|
this._fills = fills;
|
|
48
53
|
this._apolloState = apolloState;
|
|
49
54
|
this._reduxState = reduxState;
|
|
50
55
|
this._styleSheet = styleSheet;
|
|
56
|
+
this._lng = lng;
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
_transform(chunk, encoding, callback) {
|
|
54
60
|
let transformedChunk = chunk.toString();
|
|
55
61
|
|
|
62
|
+
if (transformedChunk.includes('[__ENV__]')) {
|
|
63
|
+
transformedChunk = transformedChunk.replace('[__ENV__]', JSON.stringify(publicEnv));
|
|
64
|
+
}
|
|
56
65
|
if (transformedChunk.includes('[__APOLLO_STATE__]')) {
|
|
57
66
|
transformedChunk = transformedChunk.replace(
|
|
58
67
|
'[__APOLLO_STATE__]',
|
|
@@ -71,6 +80,9 @@ class ConstantsTransform extends Transform {
|
|
|
71
80
|
if (transformedChunk.includes('[__STYLESHEET__]')) {
|
|
72
81
|
transformedChunk = transformedChunk.replace('[__STYLESHEET__]', this._styleSheet);
|
|
73
82
|
}
|
|
83
|
+
if (transformedChunk.includes('[__LOCALE__]')) {
|
|
84
|
+
transformedChunk = transformedChunk.replace('[__LOCALE__]', `"${this._lng}"`);
|
|
85
|
+
}
|
|
74
86
|
|
|
75
87
|
callback(null, transformedChunk);
|
|
76
88
|
}
|
|
@@ -86,32 +98,9 @@ export default async function handleRequest(
|
|
|
86
98
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
87
99
|
loadContext: IAppLoadContext,
|
|
88
100
|
) {
|
|
89
|
-
const instance = createInstance();
|
|
90
|
-
const lng = await i18next.getLocale(request);
|
|
91
|
-
const ns = i18next.getRouteNamespaces(remixContext);
|
|
92
|
-
|
|
93
|
-
// First, we create a new instance of i18next so every request will have a
|
|
94
|
-
// completely unique instance and not share any state.
|
|
95
|
-
if (config.i18n.enabled) {
|
|
96
|
-
await instance
|
|
97
|
-
.use(initReactI18next) // Tell our instance to use react-i18next
|
|
98
|
-
.use(Backend) // Setup our backend.init({
|
|
99
|
-
.init({
|
|
100
|
-
fallbackLng: config.i18n.fallbackLng,
|
|
101
|
-
defaultNS: config.i18n.defaultNS,
|
|
102
|
-
react: config.i18n.react,
|
|
103
|
-
supportedLngs: config.i18n.supportedLngs,
|
|
104
|
-
lng, // The locale we detected above
|
|
105
|
-
ns, // The namespaces the routes about to render want to use
|
|
106
|
-
backend: {
|
|
107
|
-
loadPath: resolve(config.i18n.backend.loadServerPath),
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
101
|
return isbot(request.headers.get('user-agent') || '')
|
|
113
|
-
? handleBotRequest(request, responseStatusCode, responseHeaders, remixContext, loadContext
|
|
114
|
-
: handleBrowserRequest(request, responseStatusCode, responseHeaders, remixContext, loadContext
|
|
102
|
+
? handleBotRequest(request, responseStatusCode, responseHeaders, remixContext, loadContext)
|
|
103
|
+
: handleBrowserRequest(request, responseStatusCode, responseHeaders, remixContext, loadContext);
|
|
115
104
|
}
|
|
116
105
|
|
|
117
106
|
function handleBotRequest(
|
|
@@ -120,14 +109,11 @@ function handleBotRequest(
|
|
|
120
109
|
responseHeaders: Headers,
|
|
121
110
|
remixContext: EntryContext,
|
|
122
111
|
loadContext: IAppLoadContext,
|
|
123
|
-
i18nInstance: i18next,
|
|
124
112
|
) {
|
|
125
113
|
return new Promise((resolve, reject) => {
|
|
126
114
|
let shellRendered = false;
|
|
127
115
|
const { pipe, abort } = renderToPipeableStream(
|
|
128
|
-
<
|
|
129
|
-
<RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />
|
|
130
|
-
</I18nextProvider>,
|
|
116
|
+
<RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />,
|
|
131
117
|
{
|
|
132
118
|
onAllReady() {
|
|
133
119
|
shellRendered = true;
|
|
@@ -164,14 +150,36 @@ function handleBotRequest(
|
|
|
164
150
|
});
|
|
165
151
|
}
|
|
166
152
|
|
|
167
|
-
function handleBrowserRequest(
|
|
153
|
+
async function handleBrowserRequest(
|
|
168
154
|
request: Request,
|
|
169
155
|
responseStatusCode: number,
|
|
170
156
|
responseHeaders: Headers,
|
|
171
157
|
remixContext: EntryContext,
|
|
172
158
|
loadContext: IAppLoadContext,
|
|
173
|
-
i18nInstance: i18next,
|
|
174
159
|
) {
|
|
160
|
+
const instance = createInstance();
|
|
161
|
+
const lng = await i18next.getLocale(request);
|
|
162
|
+
const ns = i18next.getRouteNamespaces(remixContext);
|
|
163
|
+
|
|
164
|
+
// First, we create a new instance of i18next so every request will have a
|
|
165
|
+
// completely unique instance and not share any state.
|
|
166
|
+
if (config.i18n.enabled) {
|
|
167
|
+
await instance
|
|
168
|
+
.use(initReactI18next) // Tell our instance to use react-i18next
|
|
169
|
+
.use(Backend) // Setup our backend.init({
|
|
170
|
+
.init({
|
|
171
|
+
fallbackLng: config.i18n.fallbackLng,
|
|
172
|
+
defaultNS: config.i18n.defaultNS,
|
|
173
|
+
react: config.i18n.react,
|
|
174
|
+
supportedLngs: config.i18n.supportedLngs,
|
|
175
|
+
lng, // The locale we detected above
|
|
176
|
+
ns, // The namespaces the routes about to render want to use
|
|
177
|
+
backend: {
|
|
178
|
+
loadPath: resolve(config.i18n.backend.loadServerPath),
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
175
183
|
return new Promise((resolve, reject) => {
|
|
176
184
|
let shellRendered = false;
|
|
177
185
|
const slotFillContext = { fills: {} };
|
|
@@ -190,24 +198,26 @@ function handleBrowserRequest(
|
|
|
190
198
|
|
|
191
199
|
const { pipe, abort } = renderToPipeableStream(
|
|
192
200
|
(
|
|
193
|
-
<I18nextProvider i18n={
|
|
194
|
-
<
|
|
195
|
-
<
|
|
196
|
-
<
|
|
197
|
-
<
|
|
198
|
-
<
|
|
199
|
-
<
|
|
200
|
-
<
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
201
|
+
<I18nextProvider i18n={instance}>
|
|
202
|
+
<LocaleContext.Provider value={lng}>
|
|
203
|
+
<CacheProvider value={cache}>
|
|
204
|
+
<StyleProvider cache={antdCache}>
|
|
205
|
+
<ReduxProvider store={store}>
|
|
206
|
+
<SlotFillProvider context={slotFillContext}>
|
|
207
|
+
<InversifyProvider container={container} modules={clientModules as any}>
|
|
208
|
+
<ApolloProvider client={client}>
|
|
209
|
+
<RemixServer
|
|
210
|
+
context={remixContext}
|
|
211
|
+
url={request.url}
|
|
212
|
+
abortDelay={ABORT_DELAY}
|
|
213
|
+
/>
|
|
214
|
+
</ApolloProvider>
|
|
215
|
+
</InversifyProvider>
|
|
216
|
+
</SlotFillProvider>
|
|
217
|
+
</ReduxProvider>
|
|
218
|
+
</StyleProvider>
|
|
219
|
+
</CacheProvider>
|
|
220
|
+
</LocaleContext.Provider>
|
|
211
221
|
</I18nextProvider>
|
|
212
222
|
) as any,
|
|
213
223
|
{
|
|
@@ -220,7 +230,7 @@ function handleBrowserRequest(
|
|
|
220
230
|
const fills = Object.keys(slotFillContext.fills);
|
|
221
231
|
const styleSheet = extractStyle(antdCache);
|
|
222
232
|
|
|
223
|
-
const transform = new ConstantsTransform(fills, apolloState, reduxState, styleSheet);
|
|
233
|
+
const transform = new ConstantsTransform(fills, apolloState, reduxState, styleSheet, lng);
|
|
224
234
|
|
|
225
235
|
responseHeaders.set('Content-Type', 'text/html');
|
|
226
236
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { Links, Meta, Outlet, Scripts, ScrollRestoration, useRouteLoaderData, useRouteError, json } from '@remix-run/react';
|
|
4
|
-
// @ts-ignore
|
|
5
|
-
import publicEnv from '@src/config/public-config';
|
|
6
4
|
import { PluginArea } from '@common-stack/client-react';
|
|
7
5
|
import { subscribeReduxRouter } from '@common-stack/remix-router-redux';
|
|
8
6
|
import { ApplicationErrorHandler } from '@admin-layout/ant-ui';
|
|
@@ -13,17 +11,8 @@ import clientModules, { plugins } from '@app/frontend-stack-react/modules.js';
|
|
|
13
11
|
import { useChangeLanguage } from 'remix-i18next/react';
|
|
14
12
|
import { useTranslation } from 'react-i18next';
|
|
15
13
|
// @ts-ignore
|
|
16
|
-
import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
|
|
17
|
-
// @ts-ignore
|
|
18
14
|
import { ErrorBoundary } from '@app/frontend-stack-react/entries/antui/components/ErrorBoundary';
|
|
19
|
-
|
|
20
|
-
export const loader = async ({ request }) => {
|
|
21
|
-
const locale = await i18next.getLocale(request);
|
|
22
|
-
return json({
|
|
23
|
-
__ENV__: publicEnv,
|
|
24
|
-
locale,
|
|
25
|
-
});
|
|
26
|
-
};
|
|
15
|
+
import { LocaleContext } from './context';
|
|
27
16
|
|
|
28
17
|
export const handle = {
|
|
29
18
|
i18n: 'common',
|
|
@@ -34,8 +23,8 @@ export function shouldRevalidate(params: any) {
|
|
|
34
23
|
}
|
|
35
24
|
|
|
36
25
|
export function Layout({ children }: { children: React.ReactNode }) {
|
|
37
|
-
const data = useRouteLoaderData<{ locale: any }>('root');
|
|
38
|
-
const locale =
|
|
26
|
+
// const data = useRouteLoaderData<{ locale: any }>('root');
|
|
27
|
+
const locale: any = React.useContext(LocaleContext);
|
|
39
28
|
|
|
40
29
|
const { i18n } = useTranslation();
|
|
41
30
|
|
|
@@ -49,9 +38,10 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
49
38
|
if (typeof window === 'undefined') {
|
|
50
39
|
return (
|
|
51
40
|
<>
|
|
41
|
+
<script>window.__ENV__=[__ENV__]</script>
|
|
52
42
|
<script
|
|
53
43
|
dangerouslySetInnerHTML={{
|
|
54
|
-
__html: `window.
|
|
44
|
+
__html: `window.process = {} `,
|
|
55
45
|
}}
|
|
56
46
|
/>
|
|
57
47
|
<script
|
|
@@ -68,6 +58,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
68
58
|
__html: `if (global === undefined) { var global = window; }`,
|
|
69
59
|
}}
|
|
70
60
|
/>
|
|
61
|
+
<script>window.__LOCALE__=[__LOCALE__]</script>
|
|
71
62
|
</>
|
|
72
63
|
);
|
|
73
64
|
}
|
|
@@ -18,3 +18,9 @@ export interface ClientStyleContextData {
|
|
|
18
18
|
export const ClientStyleContext = createContext<ClientStyleContextData | null>(
|
|
19
19
|
null,
|
|
20
20
|
);
|
|
21
|
+
|
|
22
|
+
export interface LocaleContextData {
|
|
23
|
+
locale: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const LocaleContext = createContext<LocaleContextData | null>(null);
|
|
@@ -6,8 +6,6 @@ import { ApolloProvider } from '@apollo/client/index.js';
|
|
|
6
6
|
import { SlotFillProvider, removeUniversalPortals } from '@common-stack/components-pro';
|
|
7
7
|
import { InversifyProvider, PluginArea } from '@common-stack/client-react';
|
|
8
8
|
import { Provider as ReduxProvider } from 'react-redux';
|
|
9
|
-
import { PersistGate } from 'redux-persist/integration/react';
|
|
10
|
-
import { persistStore } from 'redux-persist';
|
|
11
9
|
import { CacheProvider } from '@emotion/react';
|
|
12
10
|
|
|
13
11
|
// @ts-ignore
|
|
@@ -27,12 +25,10 @@ import Backend from 'i18next-http-backend';
|
|
|
27
25
|
import { getInitialNamespaces } from 'remix-i18next/client';
|
|
28
26
|
import config from '@app/cde-webconfig.json';
|
|
29
27
|
// @ts-ignore
|
|
30
|
-
|
|
31
|
-
import { ClientStyleContext } from './context';
|
|
28
|
+
import { ClientStyleContext, LocaleContext } from './context';
|
|
32
29
|
|
|
33
30
|
const { apolloClient: client, container, serviceFunc } = createClientContainer();
|
|
34
31
|
const { store } = createReduxStore(client, serviceFunc(), container);
|
|
35
|
-
const persistor = persistStore(store);
|
|
36
32
|
|
|
37
33
|
(window as any).__remixStore = store;
|
|
38
34
|
removeUniversalPortals((window as any).__SLOT_FILLS__ || []);
|
|
@@ -60,6 +56,13 @@ function ClientCacheProvider({ children }: ClientCacheProviderProps) {
|
|
|
60
56
|
);
|
|
61
57
|
}
|
|
62
58
|
|
|
59
|
+
function LocaleProvider({ children }: ClientCacheProviderProps) {
|
|
60
|
+
const el = (document as any).querySelector('html');
|
|
61
|
+
const locale = el?.getAttribute('lng') || '';
|
|
62
|
+
|
|
63
|
+
return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>;
|
|
64
|
+
}
|
|
65
|
+
|
|
63
66
|
async function hydrate() {
|
|
64
67
|
if (!i18next.isInitialized && config.i18n.enabled) {
|
|
65
68
|
await i18next
|
|
@@ -83,19 +86,19 @@ async function hydrate() {
|
|
|
83
86
|
document.getElementById('root')!,
|
|
84
87
|
// <StrictMode>
|
|
85
88
|
<I18nextProvider i18n={i18next}>
|
|
86
|
-
<
|
|
87
|
-
<
|
|
88
|
-
<
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
</
|
|
94
|
-
</
|
|
95
|
-
</
|
|
96
|
-
</
|
|
97
|
-
</
|
|
98
|
-
</
|
|
89
|
+
<LocaleProvider>
|
|
90
|
+
<ClientCacheProvider>
|
|
91
|
+
<ApolloProvider client={client}>
|
|
92
|
+
<ReduxProvider store={store}>
|
|
93
|
+
<SlotFillProvider>
|
|
94
|
+
<InversifyProvider container={container} modules={clientModules}>
|
|
95
|
+
<RemixBrowser />
|
|
96
|
+
</InversifyProvider>
|
|
97
|
+
</SlotFillProvider>
|
|
98
|
+
</ReduxProvider>
|
|
99
|
+
</ApolloProvider>
|
|
100
|
+
</ClientCacheProvider>
|
|
101
|
+
</LocaleProvider>
|
|
99
102
|
</I18nextProvider>,
|
|
100
103
|
// </StrictMode>,
|
|
101
104
|
);
|
|
@@ -36,8 +36,7 @@ import config from '@app/cde-webconfig.json';
|
|
|
36
36
|
|
|
37
37
|
import { Head } from './root';
|
|
38
38
|
import type { IAppLoadContext } from '@common-stack/client-core';
|
|
39
|
-
|
|
40
|
-
import { ServerStyleContext } from './context';
|
|
39
|
+
import { ServerStyleContext, LocaleContext } from './context';
|
|
41
40
|
import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
|
|
42
41
|
|
|
43
42
|
const { extractCriticalToChunks } = createEmotionServer(defaultCache);
|
|
@@ -149,17 +148,19 @@ async function handleBrowserRequest(
|
|
|
149
148
|
|
|
150
149
|
const html = renderToString(
|
|
151
150
|
<I18nextProvider i18n={instance}>
|
|
152
|
-
<
|
|
153
|
-
<
|
|
154
|
-
<
|
|
155
|
-
<
|
|
156
|
-
<
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
151
|
+
<LocaleContext.Provider value={lng}>
|
|
152
|
+
<CacheProvider value={defaultCache}>
|
|
153
|
+
<ApolloProvider client={client}>
|
|
154
|
+
<ReduxProvider store={store}>
|
|
155
|
+
<SlotFillProvider context={slotFillContext}>
|
|
156
|
+
<InversifyProvider container={container} modules={clientModules}>
|
|
157
|
+
<RemixServer context={remixContext} url={request.url} />
|
|
158
|
+
</InversifyProvider>
|
|
159
|
+
</SlotFillProvider>
|
|
160
|
+
</ReduxProvider>
|
|
161
|
+
</ApolloProvider>
|
|
162
|
+
</CacheProvider>
|
|
163
|
+
</LocaleContext.Provider>
|
|
163
164
|
</I18nextProvider>,
|
|
164
165
|
);
|
|
165
166
|
|
|
@@ -177,23 +178,25 @@ async function handleBrowserRequest(
|
|
|
177
178
|
const { pipe, abort } = renderToPipeableStream(
|
|
178
179
|
(
|
|
179
180
|
<I18nextProvider i18n={instance}>
|
|
180
|
-
<
|
|
181
|
-
<
|
|
182
|
-
<
|
|
183
|
-
<
|
|
184
|
-
<
|
|
185
|
-
<
|
|
186
|
-
<
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
181
|
+
<LocaleContext.Provider value={lng}>
|
|
182
|
+
<ServerStyleContext.Provider value={chunks.styles}>
|
|
183
|
+
<CacheProvider value={defaultCache}>
|
|
184
|
+
<ApolloProvider client={client}>
|
|
185
|
+
<ReduxProvider store={store}>
|
|
186
|
+
<SlotFillProvider context={slotFillContext}>
|
|
187
|
+
<InversifyProvider container={container} modules={clientModules}>
|
|
188
|
+
<RemixServer
|
|
189
|
+
context={remixContext}
|
|
190
|
+
url={request.url}
|
|
191
|
+
abortDelay={ABORT_DELAY}
|
|
192
|
+
/>
|
|
193
|
+
</InversifyProvider>
|
|
194
|
+
</SlotFillProvider>
|
|
195
|
+
</ReduxProvider>
|
|
196
|
+
</ApolloProvider>
|
|
197
|
+
</CacheProvider>
|
|
198
|
+
</ServerStyleContext.Provider>
|
|
199
|
+
</LocaleContext.Provider>
|
|
197
200
|
</I18nextProvider>
|
|
198
201
|
) as any,
|
|
199
202
|
{
|
package/src/generators/add-frontend/frameworks/chakraui/{root.tsx.template → src/root.tsx.template}
RENAMED
|
@@ -11,7 +11,7 @@ import { ApplicationErrorHandler } from '@admin-layout/chakra-ui';
|
|
|
11
11
|
import clientModules, { plugins } from '@app/frontend-stack-react/modules.js';
|
|
12
12
|
import { createHead } from 'remix-island';
|
|
13
13
|
import { useContext } from 'react';
|
|
14
|
-
import { ServerStyleContext, ClientStyleContext } from './context';
|
|
14
|
+
import { ServerStyleContext, ClientStyleContext, LocaleContext } from './context';
|
|
15
15
|
import { withEmotionCache } from '@emotion/react';
|
|
16
16
|
import { useChangeLanguage } from 'remix-i18next/react';
|
|
17
17
|
import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
|
|
@@ -31,6 +31,9 @@ export const Head = createHead(() => (
|
|
|
31
31
|
export const Document = withEmotionCache(({ children }: DocumentProps, emotionCache) => {
|
|
32
32
|
const serverStyleData = useContext(ServerStyleContext);
|
|
33
33
|
const clientStyleData = useContext(ClientStyleContext);
|
|
34
|
+
const locale = useContext(LocaleContext);
|
|
35
|
+
|
|
36
|
+
useChangeLanguage(locale);
|
|
34
37
|
|
|
35
38
|
React.useEffect(() => {
|
|
36
39
|
// re-link sheet container
|
|
@@ -64,12 +67,12 @@ export const Document = withEmotionCache(({ children }: DocumentProps, emotionCa
|
|
|
64
67
|
</>
|
|
65
68
|
);
|
|
66
69
|
});
|
|
67
|
-
|
|
70
|
+
/*
|
|
68
71
|
export let loader = async ({ request }) => {
|
|
69
72
|
let locale = await i18next.getLocale(request);
|
|
70
73
|
return json({ locale });
|
|
71
74
|
};
|
|
72
|
-
|
|
75
|
+
*/
|
|
73
76
|
export let handle = {
|
|
74
77
|
i18n: 'common',
|
|
75
78
|
};
|
|
@@ -79,11 +82,12 @@ export function shouldRevalidate(params: any) {
|
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
export default function App() {
|
|
85
|
+
/*
|
|
82
86
|
const data = useRouteLoaderData<{ locale: any }>('root');
|
|
83
87
|
const locale = data?.locale;
|
|
84
88
|
|
|
85
89
|
useChangeLanguage(locale);
|
|
86
|
-
|
|
90
|
+
*/
|
|
87
91
|
React.useEffect(() => {
|
|
88
92
|
subscribeReduxRouter({ store: window.__remixStore, router: window.__remixRouter } as any);
|
|
89
93
|
}, []);
|
|
@@ -12,8 +12,6 @@ import { ApolloProvider } from '@apollo/client/index.js';
|
|
|
12
12
|
import { SlotFillProvider, removeUniversalPortals } from '@common-stack/components-pro';
|
|
13
13
|
import { InversifyProvider } from '@common-stack/client-react';
|
|
14
14
|
import { Provider as ReduxProvider } from 'react-redux';
|
|
15
|
-
import { PersistGate } from 'redux-persist/integration/react';
|
|
16
|
-
import { persistStore } from 'redux-persist';
|
|
17
15
|
import i18next from 'i18next';
|
|
18
16
|
import { I18nextProvider, initReactI18next } from 'react-i18next';
|
|
19
17
|
import LanguageDetector from 'i18next-browser-languagedetector';
|
|
@@ -31,7 +29,6 @@ import config from '@app/cde-webconfig.json';
|
|
|
31
29
|
|
|
32
30
|
const { apolloClient: client, container, serviceFunc } = createClientContainer();
|
|
33
31
|
const { store } = createReduxStore(client, serviceFunc(), container);
|
|
34
|
-
const persistor = persistStore(store);
|
|
35
32
|
|
|
36
33
|
(window as any).__remixStore = store;
|
|
37
34
|
removeUniversalPortals((window as any).__SLOT_FILLS__ || []);
|
|
@@ -64,13 +61,9 @@ async function hydrate() {
|
|
|
64
61
|
<ReduxProvider store={store}>
|
|
65
62
|
<SlotFillProvider>
|
|
66
63
|
<InversifyProvider container={container} modules={clientModules}>
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<RemixBrowser />
|
|
71
|
-
</ApolloProvider>
|
|
72
|
-
)}
|
|
73
|
-
</PersistGate>
|
|
64
|
+
<ApolloProvider client={client}>
|
|
65
|
+
<RemixBrowser />
|
|
66
|
+
</ApolloProvider>
|
|
74
67
|
</InversifyProvider>
|
|
75
68
|
</SlotFillProvider>
|
|
76
69
|
</ReduxProvider>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* eslint-disable jest/no-hooks */
|
|
2
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
3
|
+
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
|
|
4
|
+
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
5
|
+
import { readJson, Tree, writeJson } from '@nx/devkit';
|
|
6
|
+
import * as devkit from '@nx/devkit';
|
|
7
|
+
import { addFrontendGenerator } from './generator';
|
|
8
|
+
import { FRAMEWORK_ANTUI } from '../../common/constants';
|
|
9
|
+
|
|
10
|
+
describe('addFrontendGenerator', () => {
|
|
11
|
+
let tree: Tree;
|
|
12
|
+
const options = { name: 'demo', framework: FRAMEWORK_ANTUI, ns: '', directory: '' };
|
|
13
|
+
|
|
14
|
+
const projectRoot = 'frontend-demo-server';
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
// Create an in-memory workspace
|
|
18
|
+
tree = createTreeWithEmptyWorkspace();
|
|
19
|
+
|
|
20
|
+
// Stub out generateFiles so we don't trigger file reading from the real templates folders.
|
|
21
|
+
jest.spyOn(devkit, 'generateFiles').mockImplementation(() => {});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should add missing dependencies and update config.json for antui', async () => {
|
|
25
|
+
// Simulate an existing package.json with no dependencies.
|
|
26
|
+
writeJson(tree, `${projectRoot}/package.json`, {
|
|
27
|
+
name: 'demo',
|
|
28
|
+
dependencies: {},
|
|
29
|
+
});
|
|
30
|
+
// Simulate an existing config.json with an empty modules array.
|
|
31
|
+
writeJson(tree, `${projectRoot}/config.json`, {
|
|
32
|
+
modules: [],
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await addFrontendGenerator(tree, options);
|
|
36
|
+
|
|
37
|
+
// Read and verify package.json updates.
|
|
38
|
+
const pkg = readJson(tree, `${projectRoot}/package.json`);
|
|
39
|
+
|
|
40
|
+
expect(pkg.name).toBe('frontend-demo-server');
|
|
41
|
+
// Check that the key dependency is added.
|
|
42
|
+
expect(pkg.dependencies['@admin-layout/ant-design-pro']).toBeDefined();
|
|
43
|
+
expect(pkg.dependencies['@ant-design/static-style-extract']).toBeDefined();
|
|
44
|
+
expect(pkg.dependencies['@emotion/react']).toBeDefined();
|
|
45
|
+
expect(pkg.dependencies['antd']).toBeDefined();
|
|
46
|
+
expect(pkg).toMatchSnapshot();
|
|
47
|
+
|
|
48
|
+
// Read and verify config.json updates.
|
|
49
|
+
const config = readJson(tree, `${projectRoot}/config.json`);
|
|
50
|
+
|
|
51
|
+
expect(config.uiFramework).toBe(FRAMEWORK_ANTUI);
|
|
52
|
+
// Ensure that the module is added only once.
|
|
53
|
+
expect(config.modules.includes('@admin-layout/ant-design-pro')).toBeTruthy();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should not override an already existing dependency version', async () => {
|
|
57
|
+
// Create an initial package.json that already defines a version for a dependency.
|
|
58
|
+
writeJson(tree, `${projectRoot}/package.json`, {
|
|
59
|
+
name: 'demo',
|
|
60
|
+
dependencies: {
|
|
61
|
+
antd: '1.0.0', // Already defined version
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
// Create a minimal config.json.
|
|
65
|
+
writeJson(tree, `${projectRoot}/config.json`, {
|
|
66
|
+
modules: [],
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
await addFrontendGenerator(tree, options);
|
|
70
|
+
|
|
71
|
+
const pkg = readJson(tree, `${projectRoot}/package.json`);
|
|
72
|
+
|
|
73
|
+
// Make sure the dependency already there was not overridden.
|
|
74
|
+
expect(pkg.dependencies.antd).toEqual('1.0.0');
|
|
75
|
+
// Ensure other expected dependencies have been added.
|
|
76
|
+
expect(pkg.dependencies['@admin-layout/ant-design-pro']).toBeDefined();
|
|
77
|
+
expect(pkg).toMatchSnapshot();
|
|
78
|
+
});
|
|
79
|
+
});
|