@shuvi/platform-web 1.0.1 → 1.0.2
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/esm/shuvi-app/app/client.js +11 -1
- package/esm/shuvi-app/app/server.js +12 -2
- package/esm/shuvi-app/helper/isThirdSite.d.ts +2 -0
- package/esm/shuvi-app/helper/isThirdSite.js +5 -0
- package/esm/shuvi-app/react/AppContainer.jsx +4 -4
- package/esm/shuvi-app/react/view/ReactView.server.jsx +6 -2
- package/lib/node/features/custom-server/server.js +4 -0
- package/lib/node/features/html-render/lib/getPageMiddleware.js +19 -2
- package/lib/node/features/html-render/serverHooks.d.ts +8 -2
- package/lib/node/features/html-render/serverHooks.js +4 -2
- package/lib/node/shuvi-runtime-server.d.ts +3 -0
- package/package.json +12 -12
|
@@ -15,6 +15,7 @@ import pageLoaders from '@shuvi/app/files/page-loaders';
|
|
|
15
15
|
import { historyMode } from '@shuvi/app/files/routerConfig';
|
|
16
16
|
import { SHUVI_ERROR } from '@shuvi/shared/lib/constants';
|
|
17
17
|
import { serializeServerError } from '../helper/serializeServerError';
|
|
18
|
+
import isThirdSite from '../helper/isThirdSite';
|
|
18
19
|
let app;
|
|
19
20
|
export const createApp = ({ routes, appData, appComponent }) => {
|
|
20
21
|
// app is a singleton in client side
|
|
@@ -98,7 +99,16 @@ export const createApp = ({ routes, appData, appComponent }) => {
|
|
|
98
99
|
}
|
|
99
100
|
catch (error) {
|
|
100
101
|
if (isRedirect(error)) {
|
|
101
|
-
|
|
102
|
+
const location = error.headers.get('Location');
|
|
103
|
+
if (isThirdSite(location)) {
|
|
104
|
+
window.location.replace(location);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
next({
|
|
108
|
+
path: location,
|
|
109
|
+
replace: true
|
|
110
|
+
});
|
|
111
|
+
}
|
|
102
112
|
return;
|
|
103
113
|
}
|
|
104
114
|
if (isResponse(error) && error.status >= 400 && error.status < 600) {
|
|
@@ -12,7 +12,7 @@ import { getRoutes, app as AppComponent } from '@shuvi/app/core/platform';
|
|
|
12
12
|
import { runLoaders, getRouteMatchesWithInvalidLoader, isResponse, isRedirect } from '@shuvi/platform-shared/shared';
|
|
13
13
|
import pageLoaders from '@shuvi/app/files/page-loaders';
|
|
14
14
|
import application from '@shuvi/platform-shared/shuvi-app/application';
|
|
15
|
-
import { createRouter, createMemoryHistory } from '@shuvi/router';
|
|
15
|
+
import { createRouter, createMemoryHistory, pathToString } from '@shuvi/router';
|
|
16
16
|
import logger from '@shuvi/utils/lib/logger';
|
|
17
17
|
import { serializeServerError } from '../helper/serializeServerError';
|
|
18
18
|
export const createApp = options => {
|
|
@@ -39,7 +39,17 @@ export const createApp = options => {
|
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
41
|
if (isRedirect(error)) {
|
|
42
|
-
|
|
42
|
+
const location = error.headers.get('Location');
|
|
43
|
+
const status = error.status;
|
|
44
|
+
next({
|
|
45
|
+
path: pathToString(to),
|
|
46
|
+
replace: true,
|
|
47
|
+
skipGuards: true,
|
|
48
|
+
state: {
|
|
49
|
+
location,
|
|
50
|
+
status
|
|
51
|
+
}
|
|
52
|
+
});
|
|
43
53
|
return;
|
|
44
54
|
}
|
|
45
55
|
if (isResponse(error) && error.status >= 400 && error.status < 600) {
|
|
@@ -12,11 +12,11 @@ function ErrorGuard({ children = null }) {
|
|
|
12
12
|
return <>{children}</>;
|
|
13
13
|
}
|
|
14
14
|
export default function AppContainer({ app, children }) {
|
|
15
|
-
return (<
|
|
16
|
-
<
|
|
15
|
+
return (<AppProvider app={app}>
|
|
16
|
+
<ErrorBoundary>
|
|
17
17
|
<Provider store={app.store}>
|
|
18
18
|
<ErrorGuard>{children}</ErrorGuard>
|
|
19
19
|
</Provider>
|
|
20
|
-
</
|
|
21
|
-
</
|
|
20
|
+
</ErrorBoundary>
|
|
21
|
+
</AppProvider>);
|
|
22
22
|
}
|
|
@@ -17,6 +17,7 @@ import Loadable, { LoadableContext } from '../loadable';
|
|
|
17
17
|
import AppContainer from '../AppContainer';
|
|
18
18
|
import { Head } from '../head';
|
|
19
19
|
import { serializeServerError } from '../../helper/serializeServerError';
|
|
20
|
+
import isThirdSite from '../../helper/isThirdSite';
|
|
20
21
|
export class ReactServerView {
|
|
21
22
|
constructor() {
|
|
22
23
|
this.renderApp = ({ req, app, manifest }) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -24,13 +25,16 @@ export class ReactServerView {
|
|
|
24
25
|
const { router, appComponent: AppComponent, setError: setAppError } = app;
|
|
25
26
|
yield router.ready;
|
|
26
27
|
// todo: move these into renderer
|
|
27
|
-
let {
|
|
28
|
+
let { matches, redirected, state, pathname } = router.current;
|
|
28
29
|
// handler no matches
|
|
29
30
|
if (!matches.length) {
|
|
30
31
|
setAppError(SHUVI_ERROR.PAGE_NOT_FOUND);
|
|
31
32
|
}
|
|
32
33
|
if (redirected) {
|
|
33
|
-
|
|
34
|
+
const { location, status } = state;
|
|
35
|
+
return redirect(isThirdSite(location)
|
|
36
|
+
? location
|
|
37
|
+
: router.resolve(location, pathname).href, status);
|
|
34
38
|
}
|
|
35
39
|
const loadableModules = [];
|
|
36
40
|
let htmlContent = undefined;
|
|
@@ -33,5 +33,9 @@ exports.default = (0, service_1.createServerPlugin)({
|
|
|
33
33
|
modifyHtml: (document, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
34
|
var _a, _b, _c;
|
|
35
35
|
yield ((_c = (_b = (_a = resources_1.default.server) === null || _a === void 0 ? void 0 : _a.server) === null || _b === void 0 ? void 0 : _b.modifyHtml) === null || _c === void 0 ? void 0 : _c.call(_b, document, context));
|
|
36
|
+
}),
|
|
37
|
+
sendHtml: (originalSendHtml) => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
var _d, _e;
|
|
39
|
+
return (((_e = (_d = resources_1.default.server.server) === null || _d === void 0 ? void 0 : _d.sendHtml) === null || _e === void 0 ? void 0 : _e.call(_d, originalSendHtml)) || originalSendHtml);
|
|
36
40
|
})
|
|
37
41
|
});
|
|
@@ -14,6 +14,11 @@ const utils_1 = require("@shuvi/service/lib/server/utils");
|
|
|
14
14
|
const shared_1 = require("@shuvi/platform-shared/shared");
|
|
15
15
|
const renderToHTML_1 = require("./renderToHTML");
|
|
16
16
|
function createPageHandler(serverPluginContext) {
|
|
17
|
+
const wrappedSendHtml = (html, { req, res }) => __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
(0, utils_1.sendHTML)(req, res, html);
|
|
19
|
+
});
|
|
20
|
+
let sendHtml;
|
|
21
|
+
let pendingSendHtml;
|
|
17
22
|
return function (req, res) {
|
|
18
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
19
24
|
const result = yield (0, renderToHTML_1.renderToHTML)({
|
|
@@ -30,7 +35,14 @@ function createPageHandler(serverPluginContext) {
|
|
|
30
35
|
else if ((0, shared_1.isText)(result)) {
|
|
31
36
|
const textResp = result;
|
|
32
37
|
res.statusCode = textResp.status;
|
|
33
|
-
(
|
|
38
|
+
if (!sendHtml) {
|
|
39
|
+
if (!pendingSendHtml) {
|
|
40
|
+
pendingSendHtml =
|
|
41
|
+
serverPluginContext.serverPluginRunner.sendHtml(wrappedSendHtml);
|
|
42
|
+
}
|
|
43
|
+
sendHtml = yield pendingSendHtml;
|
|
44
|
+
}
|
|
45
|
+
yield sendHtml(textResp.data, { req, res });
|
|
34
46
|
}
|
|
35
47
|
else {
|
|
36
48
|
// shuold never reach here
|
|
@@ -43,10 +55,15 @@ function getPageMiddleware(api) {
|
|
|
43
55
|
return __awaiter(this, void 0, void 0, function* () {
|
|
44
56
|
const defaultPageHandler = createPageHandler(api);
|
|
45
57
|
let pageHandler;
|
|
58
|
+
let pendingPageHandler;
|
|
46
59
|
return function (req, res, next) {
|
|
47
60
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
61
|
if (!pageHandler) {
|
|
49
|
-
|
|
62
|
+
if (!pendingPageHandler) {
|
|
63
|
+
pendingPageHandler =
|
|
64
|
+
api.serverPluginRunner.handlePageRequest(defaultPageHandler);
|
|
65
|
+
}
|
|
66
|
+
pageHandler = yield pendingPageHandler;
|
|
50
67
|
}
|
|
51
68
|
try {
|
|
52
69
|
yield pageHandler(req, res);
|
|
@@ -7,9 +7,15 @@ export interface ModifyHtmlContext {
|
|
|
7
7
|
req: ShuviRequest;
|
|
8
8
|
appContext: IAppContext;
|
|
9
9
|
}
|
|
10
|
-
export declare type IHandlePageRequest = (req: IncomingMessage, res: ServerResponse) =>
|
|
10
|
+
export declare type IHandlePageRequest = (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
11
|
+
export declare type RequestContext = {
|
|
12
|
+
req: IncomingMessage;
|
|
13
|
+
res: ServerResponse;
|
|
14
|
+
};
|
|
15
|
+
export declare type ISendHtml = (html: string, requestContext: RequestContext) => Promise<void>;
|
|
11
16
|
export declare const extendedHooks: {
|
|
12
17
|
getPageData: import("@shuvi/hook").AsyncParallelHook<void, IAppContext, Record<string, unknown>>;
|
|
13
|
-
handlePageRequest: import("@shuvi/hook").
|
|
18
|
+
handlePageRequest: import("@shuvi/hook").AsyncSeriesWaterfallHook<IHandlePageRequest, void>;
|
|
14
19
|
modifyHtml: import("@shuvi/hook").AsyncSeriesHook<IHtmlDocument, ModifyHtmlContext, void>;
|
|
20
|
+
sendHtml: import("@shuvi/hook").AsyncSeriesWaterfallHook<ISendHtml, void>;
|
|
15
21
|
};
|
|
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.extendedHooks = void 0;
|
|
4
4
|
const hook_1 = require("@shuvi/hook");
|
|
5
5
|
const getPageData = (0, hook_1.createAsyncParallelHook)();
|
|
6
|
-
const handlePageRequest = (0, hook_1.
|
|
6
|
+
const handlePageRequest = (0, hook_1.createAsyncSeriesWaterfallHook)();
|
|
7
7
|
const modifyHtml = (0, hook_1.createAsyncSeriesHook)();
|
|
8
|
+
const sendHtml = (0, hook_1.createAsyncSeriesWaterfallHook)();
|
|
8
9
|
exports.extendedHooks = {
|
|
9
10
|
getPageData,
|
|
10
11
|
handlePageRequest,
|
|
11
|
-
modifyHtml
|
|
12
|
+
modifyHtml,
|
|
13
|
+
sendHtml
|
|
12
14
|
};
|
|
@@ -7,6 +7,7 @@ declare global {
|
|
|
7
7
|
getPageData: typeof extendedHooks.getPageData;
|
|
8
8
|
handlePageRequest: typeof extendedHooks.handlePageRequest;
|
|
9
9
|
modifyHtml: typeof extendedHooks.modifyHtml;
|
|
10
|
+
sendHtml: typeof extendedHooks.sendHtml;
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
13
|
}
|
|
@@ -18,9 +19,11 @@ export declare type ShuviApiHandler = IApiRequestHandler;
|
|
|
18
19
|
export declare type GetPageDataFunction = RemoveLast<ServerPluginConstructor['getPageData']>;
|
|
19
20
|
export declare type HandlePageRequestFunction = RemoveLast<ServerPluginConstructor['handlePageRequest']>;
|
|
20
21
|
export declare type ModifyHtmlFunction = RemoveLast<ServerPluginConstructor['modifyHtml']>;
|
|
22
|
+
export declare type SendHtmlFunction = RemoveLast<ServerPluginConstructor['sendHtml']>;
|
|
21
23
|
export interface IServerModule {
|
|
22
24
|
getPageData?: GetPageDataFunction;
|
|
23
25
|
handlePageRequest?: HandlePageRequestFunction;
|
|
24
26
|
modifyHtml?: ModifyHtmlFunction;
|
|
27
|
+
sendHtml?: SendHtmlFunction;
|
|
25
28
|
}
|
|
26
29
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shuvi/platform-web",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/shuvijs/shuvi.git",
|
|
@@ -72,18 +72,18 @@
|
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@next/react-refresh-utils": "12.1.6",
|
|
75
|
-
"@shuvi/error-overlay": "1.0.
|
|
76
|
-
"@shuvi/hook": "1.0.
|
|
77
|
-
"@shuvi/platform-shared": "1.0.
|
|
75
|
+
"@shuvi/error-overlay": "1.0.2",
|
|
76
|
+
"@shuvi/hook": "1.0.2",
|
|
77
|
+
"@shuvi/platform-shared": "1.0.2",
|
|
78
78
|
"@shuvi/redox": "0.0.7",
|
|
79
79
|
"@shuvi/redox-react": "0.0.7",
|
|
80
|
-
"@shuvi/router": "1.0.
|
|
81
|
-
"@shuvi/router-react": "1.0.
|
|
82
|
-
"@shuvi/runtime": "1.0.
|
|
83
|
-
"@shuvi/service": "1.0.
|
|
84
|
-
"@shuvi/shared": "1.0.
|
|
85
|
-
"@shuvi/toolpack": "1.0.
|
|
86
|
-
"@shuvi/utils": "1.0.
|
|
80
|
+
"@shuvi/router": "1.0.2",
|
|
81
|
+
"@shuvi/router-react": "1.0.2",
|
|
82
|
+
"@shuvi/runtime": "1.0.2",
|
|
83
|
+
"@shuvi/service": "1.0.2",
|
|
84
|
+
"@shuvi/shared": "1.0.2",
|
|
85
|
+
"@shuvi/toolpack": "1.0.2",
|
|
86
|
+
"@shuvi/utils": "1.0.2",
|
|
87
87
|
"content-type": "1.0.4",
|
|
88
88
|
"core-js": "3.6.5",
|
|
89
89
|
"ejs": "3.1.5",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"whatwg-fetch": "3.0.0"
|
|
100
100
|
},
|
|
101
101
|
"peerDependencies": {
|
|
102
|
-
"@shuvi/service": "1.0.
|
|
102
|
+
"@shuvi/service": "1.0.2"
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
105
|
"@testing-library/react": "^13.2.0",
|