@modern-js/runtime 1.5.0 → 1.16.1
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 +48 -0
- package/dist/js/modern/cli/index.js +5 -3
- package/dist/js/modern/core/compatible.js +31 -8
- package/dist/js/modern/core/index.js +1 -1
- package/dist/js/modern/core/loader/useLoader.js +1 -1
- package/dist/js/modern/{core/runtime-context.js → runtime-context.js} +0 -0
- package/dist/js/modern/ssr/index.js +34 -13
- package/dist/js/modern/ssr/index.node.js +4 -1
- package/dist/js/modern/ssr/react/withCallback/index.js +17 -0
- package/dist/js/modern/ssr/serverRender/helmet.js +2 -2
- package/dist/js/modern/ssr/serverRender/index.js +0 -1
- package/dist/js/modern/ssr/utils.js +9 -3
- package/dist/js/node/cli/index.js +4 -2
- package/dist/js/node/core/compatible.js +32 -8
- package/dist/js/node/core/index.js +1 -1
- package/dist/js/node/core/loader/useLoader.js +1 -1
- package/dist/js/node/{core/runtime-context.js → runtime-context.js} +0 -0
- package/dist/js/node/ssr/index.js +37 -15
- package/dist/js/node/ssr/index.node.js +4 -1
- package/dist/js/node/ssr/react/withCallback/index.js +27 -0
- package/dist/js/node/ssr/serverRender/helmet.js +2 -2
- package/dist/js/node/ssr/serverRender/index.js +0 -2
- package/dist/js/node/ssr/utils.js +9 -3
- package/dist/js/treeshaking/cli/index.js +5 -3
- package/dist/js/treeshaking/core/compatible.js +65 -23
- package/dist/js/treeshaking/core/index.js +1 -1
- package/dist/js/treeshaking/core/loader/useLoader.js +1 -1
- package/dist/js/treeshaking/{core/runtime-context.js → runtime-context.js} +0 -0
- package/dist/js/treeshaking/ssr/index.js +45 -33
- package/dist/js/treeshaking/ssr/index.node.js +12 -9
- package/dist/js/treeshaking/ssr/react/withCallback/index.js +16 -0
- package/dist/js/treeshaking/ssr/serverRender/helmet.js +2 -2
- package/dist/js/treeshaking/ssr/serverRender/index.js +0 -1
- package/dist/js/treeshaking/ssr/utils.js +8 -3
- package/dist/types/core/compatible.d.ts +6 -2
- package/dist/types/core/index.d.ts +2 -2
- package/dist/types/core/plugin.d.ts +15 -8
- package/dist/types/index.d.ts +2 -1
- package/dist/types/runtime-context.d.ts +24 -0
- package/dist/types/ssr/index.d.ts +0 -7
- package/dist/types/ssr/react/nossr/index.d.ts +1 -1
- package/dist/types/ssr/react/withCallback/index.d.ts +5 -0
- package/dist/types/ssr/serverRender/index.d.ts +0 -5
- package/dist/types/state/runtime/plugin.d.ts +1 -7
- package/package.json +13 -11
- package/dist/types/core/runtime-context.d.ts +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# @modern-js/runtime
|
|
2
2
|
|
|
3
|
+
## 1.16.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fix: runtime type
|
|
8
|
+
|
|
9
|
+
fix: 修复 runtime 类型定义
|
|
10
|
+
|
|
11
|
+
## 1.16.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 1100dd58c: chore: support react 18
|
|
16
|
+
|
|
17
|
+
chore: 支持 React 18
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- a480d6ad0: fix: remove helmet regexp's global tag
|
|
22
|
+
fix: 删除 helmet 中正则匹配的全局标记
|
|
23
|
+
- Updated dependencies [641592f52]
|
|
24
|
+
- Updated dependencies [3904b30a5]
|
|
25
|
+
- Updated dependencies [1100dd58c]
|
|
26
|
+
- Updated dependencies [e04e6e76a]
|
|
27
|
+
- Updated dependencies [81c66e4a4]
|
|
28
|
+
- Updated dependencies [2c305b6f5]
|
|
29
|
+
- @modern-js/utils@1.16.0
|
|
30
|
+
- @modern-js/webpack@1.16.0
|
|
31
|
+
- @modern-js/plugin@1.16.0
|
|
32
|
+
|
|
33
|
+
## 1.15.0
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- 335c97c: fix: fix runtime context format bug
|
|
38
|
+
fix: 修复 runtimeContext 数据格式化时的问题
|
|
39
|
+
- a04a11b: fix: 修复 SSR 物理降级时,获取不到请求上下文的问题
|
|
40
|
+
fix: should get ssrContext anyway if entry is ssr enable
|
|
41
|
+
- Updated dependencies [8658a78]
|
|
42
|
+
- Updated dependencies [0df4970]
|
|
43
|
+
- Updated dependencies [05d4a4f]
|
|
44
|
+
- Updated dependencies [ad05af9]
|
|
45
|
+
- Updated dependencies [5d53d1c]
|
|
46
|
+
- Updated dependencies [37cd159]
|
|
47
|
+
- @modern-js/utils@1.15.0
|
|
48
|
+
- @modern-js/webpack@1.15.0
|
|
49
|
+
- @modern-js/plugin@1.15.0
|
|
50
|
+
|
|
3
51
|
## 1.5.0
|
|
4
52
|
|
|
5
53
|
### Minor Changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { PLUGIN_SCHEMAS, createRuntimeExportsUtils, cleanRequireCache } from '@modern-js/utils';
|
|
2
|
+
import { PLUGIN_SCHEMAS, createRuntimeExportsUtils, cleanRequireCache, isReact18 } from '@modern-js/utils';
|
|
3
3
|
import PluginState from "../state/cli";
|
|
4
4
|
import PluginSSR from "../ssr/cli";
|
|
5
5
|
import PluginRouter from "../router/cli";
|
|
@@ -11,8 +11,9 @@ export default (() => ({
|
|
|
11
11
|
let runtimeExportsUtils = {};
|
|
12
12
|
return {
|
|
13
13
|
config() {
|
|
14
|
-
const dir = api.useAppContext().internalDirectory;
|
|
14
|
+
const dir = api.useAppContext().internalDirectory || '';
|
|
15
15
|
runtimeExportsUtils = createRuntimeExportsUtils(dir, 'index');
|
|
16
|
+
process.env.IS_REACT18 = isReact18(path.join(dir, '../../')).toString();
|
|
16
17
|
return {
|
|
17
18
|
runtime: {},
|
|
18
19
|
runtimeByEntries: {},
|
|
@@ -26,7 +27,8 @@ export default (() => ({
|
|
|
26
27
|
* So need to add alias
|
|
27
28
|
*/
|
|
28
29
|
'styled-components': require.resolve('styled-components')
|
|
29
|
-
}
|
|
30
|
+
},
|
|
31
|
+
envVars: ['IS_REACT18']
|
|
30
32
|
}
|
|
31
33
|
};
|
|
32
34
|
},
|
|
@@ -11,12 +11,13 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
11
11
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
12
12
|
|
|
13
13
|
import React, { useContext, useMemo } from 'react';
|
|
14
|
-
import
|
|
14
|
+
import defaultReactDOM from 'react-dom';
|
|
15
15
|
import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
16
|
+
import { RuntimeReactContext } from "../runtime-context";
|
|
16
17
|
import { runtime } from "./plugin";
|
|
17
|
-
import { RuntimeReactContext } from "./runtime-context";
|
|
18
18
|
import { createLoaderManager } from "./loader/loaderManager";
|
|
19
19
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
|
+
const IS_REACT18 = process.env.IS_REACT18 === 'true';
|
|
20
21
|
|
|
21
22
|
function isClientArgs(id) {
|
|
22
23
|
return typeof id === 'string' || typeof HTMLElement !== 'undefined' && id instanceof HTMLElement;
|
|
@@ -105,7 +106,11 @@ export const bootstrap = async (BootApp,
|
|
|
105
106
|
* When csr, id is root id.
|
|
106
107
|
* When ssr, id is serverContext
|
|
107
108
|
*/
|
|
108
|
-
id
|
|
109
|
+
id,
|
|
110
|
+
/**
|
|
111
|
+
* root.render need use root to run function
|
|
112
|
+
*/
|
|
113
|
+
root, render = defaultReactDOM.render, hydrate = defaultReactDOM.hydrate) => {
|
|
109
114
|
let App = BootApp;
|
|
110
115
|
let runner = runnerMap.get(App); // ensure Component used is created by `createApp`
|
|
111
116
|
|
|
@@ -169,18 +174,36 @@ id) => {
|
|
|
169
174
|
context.initialData = initialData;
|
|
170
175
|
}
|
|
171
176
|
|
|
177
|
+
const rootElement = typeof id !== 'string' ? id : document.getElementById(id || 'root'); // https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
|
|
178
|
+
|
|
179
|
+
const ModernRender = App => {
|
|
180
|
+
if (IS_REACT18) {
|
|
181
|
+
root.render(App);
|
|
182
|
+
} else {
|
|
183
|
+
render(App, rootElement);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const ModernHydrate = (App, callback) => {
|
|
188
|
+
if (IS_REACT18) {
|
|
189
|
+
hydrate(rootElement, App);
|
|
190
|
+
} else {
|
|
191
|
+
hydrate(App, rootElement, callback);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
172
195
|
return runner.client({
|
|
173
196
|
App,
|
|
174
197
|
context,
|
|
175
|
-
|
|
198
|
+
ModernRender,
|
|
199
|
+
ModernHydrate
|
|
176
200
|
}, {
|
|
177
201
|
onLast: ({
|
|
178
|
-
App
|
|
179
|
-
rootElement
|
|
202
|
+
App
|
|
180
203
|
}) => {
|
|
181
|
-
|
|
204
|
+
ModernRender( /*#__PURE__*/React.createElement(App, {
|
|
182
205
|
context
|
|
183
|
-
})
|
|
206
|
+
}));
|
|
184
207
|
}
|
|
185
208
|
});
|
|
186
209
|
} else {
|
|
@@ -2,6 +2,6 @@ export { createPlugin, createRuntime, runtime, registerInit, registerPrefetch }
|
|
|
2
2
|
export { defineConfig, getConfig } from "./app-config";
|
|
3
3
|
// compatible
|
|
4
4
|
export * from "./compatible";
|
|
5
|
-
export { RuntimeReactContext } from "
|
|
5
|
+
export { RuntimeReactContext } from "../runtime-context";
|
|
6
6
|
export * from "./loader";
|
|
7
7
|
export * from '@modern-js/plugin';
|
|
@@ -6,7 +6,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
6
6
|
|
|
7
7
|
import { useContext, useRef, useMemo, useState, useCallback, useEffect } from 'react';
|
|
8
8
|
import invariant from 'invariant';
|
|
9
|
-
import { RuntimeReactContext } from "
|
|
9
|
+
import { RuntimeReactContext } from "../../runtime-context";
|
|
10
10
|
import { LoaderStatus } from "./loaderManager";
|
|
11
11
|
|
|
12
12
|
const useLoader = (loaderFn, options = {
|
|
File without changes
|
|
@@ -4,11 +4,13 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
4
4
|
|
|
5
5
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
6
|
|
|
7
|
-
import ReactDOM from 'react-dom';
|
|
8
7
|
import { loadableReady } from '@loadable/component';
|
|
8
|
+
import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
9
9
|
import { RenderLevel } from "./serverRender/type";
|
|
10
|
+
import { WithCallback } from "./react/withCallback";
|
|
10
11
|
import { formatClient, mockResponse } from "./utils";
|
|
11
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
const IS_REACT18 = process.env.IS_REACT18 === 'true';
|
|
12
14
|
|
|
13
15
|
const ssr = () => ({
|
|
14
16
|
name: '@modern-js/plugin-ssr',
|
|
@@ -18,37 +20,52 @@ const ssr = () => ({
|
|
|
18
20
|
client: async ({
|
|
19
21
|
App,
|
|
20
22
|
context,
|
|
21
|
-
|
|
23
|
+
ModernRender,
|
|
24
|
+
ModernHydrate
|
|
22
25
|
}) => {
|
|
23
26
|
var _window, _window$_SSR_DATA;
|
|
24
27
|
|
|
25
28
|
const renderLevel = (_window = window) === null || _window === void 0 ? void 0 : (_window$_SSR_DATA = _window._SSR_DATA) === null || _window$_SSR_DATA === void 0 ? void 0 : _window$_SSR_DATA.renderLevel;
|
|
26
29
|
|
|
27
30
|
if (renderLevel === RenderLevel.CLIENT_RENDER) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
ReactDOM.render( /*#__PURE__*/_jsx(App, {
|
|
31
|
+
// prefetch block render while csr
|
|
32
|
+
// await (App as any)?.prefetch?.(context);
|
|
33
|
+
ModernRender( /*#__PURE__*/_jsx(App, {
|
|
32
34
|
context: context
|
|
33
|
-
})
|
|
35
|
+
}));
|
|
34
36
|
} else if (renderLevel === RenderLevel.SERVER_RENDER) {
|
|
35
37
|
loadableReady(() => {
|
|
36
38
|
const hydrateContext = _objectSpread(_objectSpread({}, context), {}, {
|
|
37
39
|
_hydration: true
|
|
38
40
|
});
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
context: hydrateContext
|
|
42
|
-
}), rootElement, () => {
|
|
42
|
+
const callback = () => {
|
|
43
43
|
// won't cause component re-render because context's reference identity doesn't change
|
|
44
44
|
delete hydrateContext._hydration;
|
|
45
|
-
}
|
|
45
|
+
}; // callback: https://github.com/reactwg/react-18/discussions/5
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if (IS_REACT18) {
|
|
49
|
+
let SSRApp = () => /*#__PURE__*/_jsx(WithCallback, {
|
|
50
|
+
callback: callback,
|
|
51
|
+
children: /*#__PURE__*/_jsx(App, {
|
|
52
|
+
context: hydrateContext
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
SSRApp = hoistNonReactStatics(SSRApp, App);
|
|
57
|
+
ModernHydrate( /*#__PURE__*/_jsx(SSRApp, {}));
|
|
58
|
+
} else {
|
|
59
|
+
ModernHydrate( /*#__PURE__*/_jsx(App, {
|
|
60
|
+
context: hydrateContext
|
|
61
|
+
}), callback);
|
|
62
|
+
}
|
|
46
63
|
});
|
|
47
64
|
} else {
|
|
48
65
|
// unknown renderlevel or renderlevel is server prefetch.
|
|
49
|
-
|
|
66
|
+
ModernHydrate( /*#__PURE__*/_jsx(App, {
|
|
50
67
|
context: context
|
|
51
|
-
})
|
|
68
|
+
}));
|
|
52
69
|
}
|
|
53
70
|
},
|
|
54
71
|
|
|
@@ -60,6 +77,10 @@ const ssr = () => ({
|
|
|
60
77
|
const request = (_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$_SSR_DATA = _window2._SSR_DATA) === null || _window2$_SSR_DATA === void 0 ? void 0 : (_window2$_SSR_DATA$co = _window2$_SSR_DATA.context) === null || _window2$_SSR_DATA$co === void 0 ? void 0 : _window2$_SSR_DATA$co.request;
|
|
61
78
|
|
|
62
79
|
if (!request) {
|
|
80
|
+
context.ssrContext = _objectSpread(_objectSpread({}, context.ssrContext), {}, {
|
|
81
|
+
response: mockResp,
|
|
82
|
+
request: formatClient({})
|
|
83
|
+
});
|
|
63
84
|
return next({
|
|
64
85
|
context
|
|
65
86
|
});
|
|
@@ -28,7 +28,9 @@ const plugin = () => ({
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
if (!isBrowser()) {
|
|
31
|
-
|
|
31
|
+
var _context$ssrContext;
|
|
32
|
+
|
|
33
|
+
const html = await require("./serverRender").render(context, (context === null || context === void 0 ? void 0 : (_context$ssrContext = context.ssrContext) === null || _context$ssrContext === void 0 ? void 0 : _context$ssrContext.distDir) || path.join(process.cwd(), 'dist'), App);
|
|
32
34
|
return html;
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -51,6 +53,7 @@ const plugin = () => ({
|
|
|
51
53
|
context,
|
|
52
54
|
pickedContext
|
|
53
55
|
}, next) => {
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
|
|
54
57
|
const {
|
|
55
58
|
request,
|
|
56
59
|
response
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// See https://github.com/reactwg/react-18/discussions/5#discussioncomment-2276079
|
|
2
|
+
import { useRef, useLayoutEffect } from 'react';
|
|
3
|
+
export const WithCallback = ({
|
|
4
|
+
callback,
|
|
5
|
+
children
|
|
6
|
+
}) => {
|
|
7
|
+
const once = useRef(false);
|
|
8
|
+
useLayoutEffect(() => {
|
|
9
|
+
if (once.current) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
once.current = true;
|
|
14
|
+
callback();
|
|
15
|
+
}, [callback]);
|
|
16
|
+
return children;
|
|
17
|
+
};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
const RE_HTML_ATTR = /<html[^>]*>/;
|
|
3
3
|
const RE_BODY_ATTR = /<body[^>]*>/;
|
|
4
4
|
const RE_LAST_IN_HEAD = /<\/head>/;
|
|
5
|
-
const RE_TITLE = /<title[^>]*>([\s\S\n\r]*?)<\/title
|
|
6
|
-
const TEST_TITLE_CONTENT = /(?<=<title[^>]*>)([\s\S\n\r]*?)([.|\S])([\s\S\n\r]*?)(?=<\/title>)
|
|
5
|
+
const RE_TITLE = /<title[^>]*>([\s\S\n\r]*?)<\/title>/;
|
|
6
|
+
const TEST_TITLE_CONTENT = /(?<=<title[^>]*>)([\s\S\n\r]*?)([.|\S])([\s\S\n\r]*?)(?=<\/title>)/; // 通过 react-helmet 修改模板
|
|
7
7
|
|
|
8
8
|
export default function helmet(content, helmetData) {
|
|
9
9
|
let result = content;
|
|
@@ -19,19 +19,25 @@ export const formatServer = request => {
|
|
|
19
19
|
|
|
20
20
|
const getQuery = () => window.location.search.substring(1).split('&').reduce((res, item) => {
|
|
21
21
|
const [key, value] = item.split('=');
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
if (key) {
|
|
24
|
+
res[key] = value;
|
|
25
|
+
}
|
|
26
|
+
|
|
23
27
|
return res;
|
|
24
28
|
}, {});
|
|
25
29
|
|
|
26
30
|
export const formatClient = request => {
|
|
31
|
+
var _request$headers, _request$headers2;
|
|
32
|
+
|
|
27
33
|
return {
|
|
28
34
|
params: request.params || {},
|
|
29
35
|
host: request.host || location.host,
|
|
30
36
|
pathname: request.pathname || location.pathname,
|
|
31
37
|
headers: request.headers || {},
|
|
32
38
|
cookieMap: request.cookieMap || {},
|
|
33
|
-
cookie: request.headers.cookie || document.cookie,
|
|
34
|
-
userAgent: request.headers['user-agent'] || navigator.userAgent,
|
|
39
|
+
cookie: ((_request$headers = request.headers) === null || _request$headers === void 0 ? void 0 : _request$headers.cookie) || document.cookie,
|
|
40
|
+
userAgent: ((_request$headers2 = request.headers) === null || _request$headers2 === void 0 ? void 0 : _request$headers2['user-agent']) || navigator.userAgent,
|
|
35
41
|
referer: request.referer || document.referrer,
|
|
36
42
|
query: request.query || getQuery(),
|
|
37
43
|
url: location.href
|
|
@@ -25,8 +25,9 @@ var _default = () => ({
|
|
|
25
25
|
let runtimeExportsUtils = {};
|
|
26
26
|
return {
|
|
27
27
|
config() {
|
|
28
|
-
const dir = api.useAppContext().internalDirectory;
|
|
28
|
+
const dir = api.useAppContext().internalDirectory || '';
|
|
29
29
|
runtimeExportsUtils = (0, _utils.createRuntimeExportsUtils)(dir, 'index');
|
|
30
|
+
process.env.IS_REACT18 = (0, _utils.isReact18)(_path.default.join(dir, '../../')).toString();
|
|
30
31
|
return {
|
|
31
32
|
runtime: {},
|
|
32
33
|
runtimeByEntries: {},
|
|
@@ -40,7 +41,8 @@ var _default = () => ({
|
|
|
40
41
|
* So need to add alias
|
|
41
42
|
*/
|
|
42
43
|
'styled-components': require.resolve('styled-components')
|
|
43
|
-
}
|
|
44
|
+
},
|
|
45
|
+
envVars: ['IS_REACT18']
|
|
44
46
|
}
|
|
45
47
|
};
|
|
46
48
|
},
|
|
@@ -11,9 +11,9 @@ var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
|
11
11
|
|
|
12
12
|
var _hoistNonReactStatics = _interopRequireDefault(require("hoist-non-react-statics"));
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _runtimeContext = require("../runtime-context");
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var _plugin = require("./plugin");
|
|
17
17
|
|
|
18
18
|
var _loaderManager = require("./loader/loaderManager");
|
|
19
19
|
|
|
@@ -37,6 +37,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
37
37
|
|
|
38
38
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
39
39
|
|
|
40
|
+
const IS_REACT18 = process.env.IS_REACT18 === 'true';
|
|
41
|
+
|
|
40
42
|
function isClientArgs(id) {
|
|
41
43
|
return typeof id === 'string' || typeof HTMLElement !== 'undefined' && id instanceof HTMLElement;
|
|
42
44
|
}
|
|
@@ -129,7 +131,11 @@ const bootstrap = async (BootApp,
|
|
|
129
131
|
* When csr, id is root id.
|
|
130
132
|
* When ssr, id is serverContext
|
|
131
133
|
*/
|
|
132
|
-
id
|
|
134
|
+
id,
|
|
135
|
+
/**
|
|
136
|
+
* root.render need use root to run function
|
|
137
|
+
*/
|
|
138
|
+
root, render = _reactDom.default.render, hydrate = _reactDom.default.hydrate) => {
|
|
133
139
|
let App = BootApp;
|
|
134
140
|
let runner = runnerMap.get(App); // ensure Component used is created by `createApp`
|
|
135
141
|
|
|
@@ -193,18 +199,36 @@ id) => {
|
|
|
193
199
|
context.initialData = initialData;
|
|
194
200
|
}
|
|
195
201
|
|
|
202
|
+
const rootElement = typeof id !== 'string' ? id : document.getElementById(id || 'root'); // https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
|
|
203
|
+
|
|
204
|
+
const ModernRender = App => {
|
|
205
|
+
if (IS_REACT18) {
|
|
206
|
+
root.render(App);
|
|
207
|
+
} else {
|
|
208
|
+
render(App, rootElement);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const ModernHydrate = (App, callback) => {
|
|
213
|
+
if (IS_REACT18) {
|
|
214
|
+
hydrate(rootElement, App);
|
|
215
|
+
} else {
|
|
216
|
+
hydrate(App, rootElement, callback);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
196
220
|
return runner.client({
|
|
197
221
|
App,
|
|
198
222
|
context,
|
|
199
|
-
|
|
223
|
+
ModernRender,
|
|
224
|
+
ModernHydrate
|
|
200
225
|
}, {
|
|
201
226
|
onLast: ({
|
|
202
|
-
App
|
|
203
|
-
rootElement
|
|
227
|
+
App
|
|
204
228
|
}) => {
|
|
205
|
-
|
|
229
|
+
ModernRender( /*#__PURE__*/_react.default.createElement(App, {
|
|
206
230
|
context
|
|
207
|
-
})
|
|
231
|
+
}));
|
|
208
232
|
}
|
|
209
233
|
});
|
|
210
234
|
} else {
|
|
@@ -9,7 +9,7 @@ var _react = require("react");
|
|
|
9
9
|
|
|
10
10
|
var _invariant = _interopRequireDefault(require("invariant"));
|
|
11
11
|
|
|
12
|
-
var _runtimeContext = require("
|
|
12
|
+
var _runtimeContext = require("../../runtime-context");
|
|
13
13
|
|
|
14
14
|
var _loaderManager = require("./loaderManager");
|
|
15
15
|
|
|
File without changes
|
|
@@ -6,12 +6,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
var _exportNames = {};
|
|
7
7
|
exports.default = void 0;
|
|
8
8
|
|
|
9
|
-
var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
10
|
-
|
|
11
9
|
var _component = require("@loadable/component");
|
|
12
10
|
|
|
11
|
+
var _hoistNonReactStatics = _interopRequireDefault(require("hoist-non-react-statics"));
|
|
12
|
+
|
|
13
13
|
var _type = require("./serverRender/type");
|
|
14
14
|
|
|
15
|
+
var _withCallback = require("./react/withCallback");
|
|
16
|
+
|
|
15
17
|
var _utils = require("./utils");
|
|
16
18
|
|
|
17
19
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -38,6 +40,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
38
40
|
|
|
39
41
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
40
42
|
|
|
43
|
+
const IS_REACT18 = process.env.IS_REACT18 === 'true';
|
|
44
|
+
|
|
41
45
|
const ssr = () => ({
|
|
42
46
|
name: '@modern-js/plugin-ssr',
|
|
43
47
|
setup: () => {
|
|
@@ -46,38 +50,52 @@ const ssr = () => ({
|
|
|
46
50
|
client: async ({
|
|
47
51
|
App,
|
|
48
52
|
context,
|
|
49
|
-
|
|
53
|
+
ModernRender,
|
|
54
|
+
ModernHydrate
|
|
50
55
|
}) => {
|
|
51
56
|
var _window, _window$_SSR_DATA;
|
|
52
57
|
|
|
53
58
|
const renderLevel = (_window = window) === null || _window === void 0 ? void 0 : (_window$_SSR_DATA = _window._SSR_DATA) === null || _window$_SSR_DATA === void 0 ? void 0 : _window$_SSR_DATA.renderLevel;
|
|
54
59
|
|
|
55
60
|
if (renderLevel === _type.RenderLevel.CLIENT_RENDER) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
_reactDom.default.render( /*#__PURE__*/(0, _jsxRuntime.jsx)(App, {
|
|
61
|
+
// prefetch block render while csr
|
|
62
|
+
// await (App as any)?.prefetch?.(context);
|
|
63
|
+
ModernRender( /*#__PURE__*/(0, _jsxRuntime.jsx)(App, {
|
|
61
64
|
context: context
|
|
62
|
-
})
|
|
65
|
+
}));
|
|
63
66
|
} else if (renderLevel === _type.RenderLevel.SERVER_RENDER) {
|
|
64
67
|
(0, _component.loadableReady)(() => {
|
|
65
68
|
const hydrateContext = _objectSpread(_objectSpread({}, context), {}, {
|
|
66
69
|
_hydration: true
|
|
67
70
|
});
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
context: hydrateContext
|
|
71
|
-
}), rootElement, () => {
|
|
72
|
+
const callback = () => {
|
|
72
73
|
// won't cause component re-render because context's reference identity doesn't change
|
|
73
74
|
delete hydrateContext._hydration;
|
|
74
|
-
}
|
|
75
|
+
}; // callback: https://github.com/reactwg/react-18/discussions/5
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if (IS_REACT18) {
|
|
79
|
+
let SSRApp = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_withCallback.WithCallback, {
|
|
80
|
+
callback: callback,
|
|
81
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(App, {
|
|
82
|
+
context: hydrateContext
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
SSRApp = (0, _hoistNonReactStatics.default)(SSRApp, App);
|
|
87
|
+
ModernHydrate( /*#__PURE__*/(0, _jsxRuntime.jsx)(SSRApp, {}));
|
|
88
|
+
} else {
|
|
89
|
+
ModernHydrate( /*#__PURE__*/(0, _jsxRuntime.jsx)(App, {
|
|
90
|
+
context: hydrateContext
|
|
91
|
+
}), callback);
|
|
92
|
+
}
|
|
75
93
|
});
|
|
76
94
|
} else {
|
|
77
95
|
// unknown renderlevel or renderlevel is server prefetch.
|
|
78
|
-
|
|
96
|
+
ModernHydrate( /*#__PURE__*/(0, _jsxRuntime.jsx)(App, {
|
|
79
97
|
context: context
|
|
80
|
-
})
|
|
98
|
+
}));
|
|
81
99
|
}
|
|
82
100
|
},
|
|
83
101
|
|
|
@@ -89,6 +107,10 @@ const ssr = () => ({
|
|
|
89
107
|
const request = (_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$_SSR_DATA = _window2._SSR_DATA) === null || _window2$_SSR_DATA === void 0 ? void 0 : (_window2$_SSR_DATA$co = _window2$_SSR_DATA.context) === null || _window2$_SSR_DATA$co === void 0 ? void 0 : _window2$_SSR_DATA$co.request;
|
|
90
108
|
|
|
91
109
|
if (!request) {
|
|
110
|
+
context.ssrContext = _objectSpread(_objectSpread({}, context.ssrContext), {}, {
|
|
111
|
+
response: mockResp,
|
|
112
|
+
request: (0, _utils.formatClient)({})
|
|
113
|
+
});
|
|
92
114
|
return next({
|
|
93
115
|
context
|
|
94
116
|
});
|
|
@@ -54,7 +54,9 @@ const plugin = () => ({
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
if (!(0, _common.isBrowser)()) {
|
|
57
|
-
|
|
57
|
+
var _context$ssrContext;
|
|
58
|
+
|
|
59
|
+
const html = await require("./serverRender").render(context, (context === null || context === void 0 ? void 0 : (_context$ssrContext = context.ssrContext) === null || _context$ssrContext === void 0 ? void 0 : _context$ssrContext.distDir) || _path.default.join(process.cwd(), 'dist'), App);
|
|
58
60
|
return html;
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -77,6 +79,7 @@ const plugin = () => ({
|
|
|
77
79
|
context,
|
|
78
80
|
pickedContext
|
|
79
81
|
}, next) => {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
|
|
80
83
|
const {
|
|
81
84
|
request,
|
|
82
85
|
response
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.WithCallback = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
// See https://github.com/reactwg/react-18/discussions/5#discussioncomment-2276079
|
|
11
|
+
const WithCallback = ({
|
|
12
|
+
callback,
|
|
13
|
+
children
|
|
14
|
+
}) => {
|
|
15
|
+
const once = (0, _react.useRef)(false);
|
|
16
|
+
(0, _react.useLayoutEffect)(() => {
|
|
17
|
+
if (once.current) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
once.current = true;
|
|
22
|
+
callback();
|
|
23
|
+
}, [callback]);
|
|
24
|
+
return children;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.WithCallback = WithCallback;
|
|
@@ -8,8 +8,8 @@ exports.default = helmet;
|
|
|
8
8
|
const RE_HTML_ATTR = /<html[^>]*>/;
|
|
9
9
|
const RE_BODY_ATTR = /<body[^>]*>/;
|
|
10
10
|
const RE_LAST_IN_HEAD = /<\/head>/;
|
|
11
|
-
const RE_TITLE = /<title[^>]*>([\s\S\n\r]*?)<\/title
|
|
12
|
-
const TEST_TITLE_CONTENT = /(?<=<title[^>]*>)([\s\S\n\r]*?)([.|\S])([\s\S\n\r]*?)(?=<\/title>)
|
|
11
|
+
const RE_TITLE = /<title[^>]*>([\s\S\n\r]*?)<\/title>/;
|
|
12
|
+
const TEST_TITLE_CONTENT = /(?<=<title[^>]*>)([\s\S\n\r]*?)([.|\S])([\s\S\n\r]*?)(?=<\/title>)/; // 通过 react-helmet 修改模板
|
|
13
13
|
|
|
14
14
|
function helmet(content, helmetData) {
|
|
15
15
|
let result = content;
|