@shuvi/platform-web 1.0.0-rc.2 → 1.0.0-rc.5
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/shared/appTypes.d.ts +2 -2
- package/esm/shared/renderTypes.d.ts +2 -2
- package/esm/shuvi-app/app/client.d.ts +2 -0
- package/esm/shuvi-app/app/client.js +12 -11
- package/esm/shuvi-app/app/server.js +4 -5
- package/esm/shuvi-app/dev/eventsource.d.ts +1 -0
- package/esm/shuvi-app/dev/eventsource.js +60 -0
- package/esm/shuvi-app/dev/hotDevClient.d.ts +33 -0
- package/esm/shuvi-app/dev/hotDevClient.js +348 -0
- package/esm/shuvi-app/dev/index.d.ts +3 -0
- package/esm/shuvi-app/dev/index.js +27 -0
- package/esm/shuvi-app/dev/websocket.d.ts +17 -0
- package/esm/shuvi-app/dev/websocket.js +61 -0
- package/esm/shuvi-app/entry/client/app.d.ts +2 -1
- package/esm/shuvi-app/entry/client/app.js +2 -2
- package/esm/shuvi-app/entry/client/run.dev.js +4 -4
- package/esm/shuvi-app/entry/server/index.d.ts +5 -4
- package/esm/shuvi-app/entry/server/index.js +5 -4
- package/esm/shuvi-app/react/AppContainer.d.ts +2 -3
- package/esm/shuvi-app/react/AppContainer.jsx +3 -4
- package/esm/shuvi-app/react/getRoutes.d.ts +2 -2
- package/esm/shuvi-app/react/getRoutes.js +6 -7
- package/esm/shuvi-app/react/redox-react/RedoxWrapper.d.ts +2 -2
- package/esm/shuvi-app/react/redox-react/RedoxWrapper.jsx +3 -3
- package/esm/shuvi-app/react/redox-react/runtime.d.ts +7 -1
- package/esm/shuvi-app/react/redox-react/runtime.js +3 -1
- package/esm/shuvi-app/react/store.d.ts +5 -0
- package/esm/shuvi-app/react/store.js +3 -0
- package/esm/shuvi-app/react/types.d.ts +0 -7
- package/esm/shuvi-app/react/useLoaderData.js +11 -20
- package/esm/shuvi-app/react/view/ReactView.client.jsx +4 -4
- package/esm/shuvi-app/react/view/ReactView.server.jsx +4 -10
- package/esm/shuvi-app/shuvi-runtime-index.js +1 -1
- package/lib/node/features/filesystem-routes/index.d.ts +1 -1
- package/lib/node/features/filesystem-routes/index.js +17 -7
- package/lib/node/features/filesystem-routes/page/routes.d.ts +2 -2
- package/lib/node/features/filesystem-routes/page/routes.js +29 -11
- package/lib/node/features/html-render/index.d.ts +3 -18
- package/lib/node/features/html-render/index.js +87 -16
- package/lib/node/features/{main → html-render/lib}/buildHtml.d.ts +0 -0
- package/lib/node/features/{main → html-render/lib}/buildHtml.js +0 -0
- package/lib/node/features/html-render/lib/generateFilesByRoutId.d.ts +2 -2
- package/lib/node/features/html-render/lib/generateFilesByRoutId.js +3 -3
- package/lib/node/features/{main → html-render/lib}/generateResource.d.ts +0 -0
- package/lib/node/features/{main → html-render/lib}/generateResource.js +0 -0
- package/lib/node/features/html-render/lib/index.d.ts +0 -1
- package/lib/node/features/html-render/lib/index.js +1 -3
- package/lib/node/features/html-render/lib/renderToHTML.js +4 -47
- package/lib/node/features/html-render/lib/renderer/base.d.ts +4 -4
- package/lib/node/features/html-render/lib/renderer/index.d.ts +5 -4
- package/lib/node/features/html-render/lib/renderer/index.js +69 -6
- package/lib/node/features/html-render/lib/renderer/spa.d.ts +2 -2
- package/lib/node/features/html-render/lib/renderer/spa.js +2 -4
- package/lib/node/features/html-render/lib/renderer/ssr.d.ts +2 -2
- package/lib/node/features/html-render/lib/renderer/ssr.js +2 -2
- package/lib/node/features/html-render/lib/renderer/types.d.ts +6 -4
- package/lib/node/features/index.d.ts +3 -31
- package/lib/node/features/index.js +6 -7
- package/lib/node/features/model/index.d.ts +1 -1
- package/lib/node/features/model/runtime.d.ts +0 -5
- package/lib/node/features/model/runtime.js +11 -17
- package/lib/node/features/model/server.js +2 -3
- package/lib/node/features/model/shuvi-app.d.ts +1 -1
- package/lib/node/features/on-demand-compile-page/index.d.ts +15 -13
- package/lib/node/features/on-demand-compile-page/index.js +4 -1
- package/lib/node/features/on-demand-compile-page/onDemandRouteManager.js +2 -4
- package/lib/node/index.js +1 -3
- package/lib/node/shuvi-runtime-server.d.ts +18 -0
- package/lib/node/shuvi-runtime-server.js +2 -0
- package/lib/node/shuvi-type-extensions-node.d.ts +2 -6
- package/lib/node/targets/react/bundler/index.d.ts +1 -1
- package/lib/node/targets/react/bundler/index.js +5 -0
- package/lib/node/targets/react/index.d.ts +2 -2
- package/lib/node/targets/react/redox-react/index.d.ts +1 -1
- package/lib/shared/appTypes.d.ts +2 -2
- package/lib/shared/renderTypes.d.ts +2 -2
- package/package.json +17 -12
- package/shuvi-env.d.ts +10 -0
- package/shuvi-image.d.ts +54 -0
- package/shuvi-type-extensions-node.js +1 -0
- package/shuvi-type-extensions-runtime.d.ts +2 -2
- package/esm/shuvi-app/dev/webpackHotDevClient.d.ts +0 -5
- package/esm/shuvi-app/dev/webpackHotDevClient.js +0 -34
- package/esm/shuvi-app/shuvi-runtime-server.d.ts +0 -6
- package/esm/shuvi-app/shuvi-runtime-server.js +0 -1
- package/lib/node/features/main/index.d.ts +0 -3
- package/lib/node/features/main/index.js +0 -82
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
let source;
|
|
2
|
+
const eventCallbacks = [];
|
|
3
|
+
let lastActivity = Date.now();
|
|
4
|
+
let initDataBeforeWsOnline = [];
|
|
5
|
+
function getSocketProtocol(protocol) {
|
|
6
|
+
return protocol === 'http:' ? 'ws' : 'wss';
|
|
7
|
+
}
|
|
8
|
+
export function addMessageListener(cb) {
|
|
9
|
+
eventCallbacks.push(cb);
|
|
10
|
+
}
|
|
11
|
+
export function sendMessage(data) {
|
|
12
|
+
if (!source || source.readyState !== source.OPEN) {
|
|
13
|
+
initDataBeforeWsOnline.push(data);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
return source.send(data);
|
|
17
|
+
}
|
|
18
|
+
export function connectHMR(options) {
|
|
19
|
+
if (!options.timeout) {
|
|
20
|
+
options.timeout = 5000;
|
|
21
|
+
}
|
|
22
|
+
init();
|
|
23
|
+
let timer = setInterval(function () {
|
|
24
|
+
if (Date.now() - lastActivity > options.timeout) {
|
|
25
|
+
handleDisconnect();
|
|
26
|
+
}
|
|
27
|
+
}, options.timeout / 2);
|
|
28
|
+
function init() {
|
|
29
|
+
if (source)
|
|
30
|
+
source.close();
|
|
31
|
+
let { protocol, hostname, port } = options.location;
|
|
32
|
+
protocol = getSocketProtocol(protocol);
|
|
33
|
+
let url = `${protocol}://${hostname}:${port}`;
|
|
34
|
+
source = new WebSocket(`${url}${options.path}`);
|
|
35
|
+
source.onopen = handleOnline;
|
|
36
|
+
source.onerror = handleDisconnect;
|
|
37
|
+
source.onmessage = handleMessage;
|
|
38
|
+
}
|
|
39
|
+
function handleOnline() {
|
|
40
|
+
if (initDataBeforeWsOnline.length !== 0) {
|
|
41
|
+
initDataBeforeWsOnline.forEach(data => {
|
|
42
|
+
sendMessage(data);
|
|
43
|
+
});
|
|
44
|
+
initDataBeforeWsOnline = [];
|
|
45
|
+
}
|
|
46
|
+
if (options.log)
|
|
47
|
+
console.log('[HMR] connected');
|
|
48
|
+
lastActivity = Date.now();
|
|
49
|
+
}
|
|
50
|
+
function handleMessage(event) {
|
|
51
|
+
lastActivity = Date.now();
|
|
52
|
+
eventCallbacks.forEach(cb => {
|
|
53
|
+
cb(event);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function handleDisconnect() {
|
|
57
|
+
clearInterval(timer);
|
|
58
|
+
source.close();
|
|
59
|
+
setTimeout(init, options.timeout);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { CLIENT_CONTAINER_ID } from '@shuvi/shared/lib/constants';
|
|
11
11
|
// renderer must be imported before application
|
|
12
|
-
// we need to init
|
|
12
|
+
// we need to init renderer before import AppComponent
|
|
13
13
|
import { view, getRoutes, app as PlatformAppComponent } from '@shuvi/app/core/platform';
|
|
14
14
|
import routes from '@shuvi/app/files/routes';
|
|
15
15
|
import { getAppData } from '@shuvi/platform-shared/shared/helper/getAppData';
|
|
@@ -32,7 +32,7 @@ const run = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
32
32
|
yield app.init();
|
|
33
33
|
render();
|
|
34
34
|
});
|
|
35
|
-
export { run };
|
|
35
|
+
export { run, app };
|
|
36
36
|
if (module.hot) {
|
|
37
37
|
const handleHotUpdate = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
38
|
const rerender = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -9,11 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
/// <reference lib="dom" />
|
|
11
11
|
import { DEV_STYLE_HIDE_FOUC, DEV_STYLE_PREPARE } from '@shuvi/shared/lib/constants';
|
|
12
|
-
import
|
|
13
|
-
import { run } from './app';
|
|
12
|
+
import { initHMRAndDevClient } from '../../dev';
|
|
13
|
+
import { run, app } from './app';
|
|
14
14
|
function init() {
|
|
15
15
|
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
-
|
|
16
|
+
initHMRAndDevClient(app);
|
|
17
17
|
// reduce FOUC caused by style-loader
|
|
18
18
|
const styleReady = new Promise(resolve => {
|
|
19
19
|
(window.requestAnimationFrame || setTimeout)(() => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -27,4 +27,4 @@ function init() {
|
|
|
27
27
|
yield styleReady;
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
|
-
init().then(run);
|
|
30
|
+
init().then(() => run());
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as server from '@shuvi/app/user/server';
|
|
1
|
+
import { default as pageRoutes } from '@shuvi/app/files/routes';
|
|
3
2
|
import { default as apiRoutes } from '@shuvi/app/files/apiRoutes';
|
|
4
3
|
import { default as middlewareRoutes } from '@shuvi/app/files/middlewareRoutes';
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import { view } from '@shuvi/app/core/platform';
|
|
5
|
+
import * as server from '@shuvi/app/user/server';
|
|
6
|
+
import * as application from '../../app/server';
|
|
7
|
+
export { pageRoutes, apiRoutes, middlewareRoutes, server, view, application };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// This is the shuvi server-side main module exports collection
|
|
2
|
-
import
|
|
3
|
-
import * as server from '@shuvi/app/user/server';
|
|
2
|
+
import { default as pageRoutes } from '@shuvi/app/files/routes';
|
|
4
3
|
import { default as apiRoutes } from '@shuvi/app/files/apiRoutes';
|
|
5
4
|
import { default as middlewareRoutes } from '@shuvi/app/files/middlewareRoutes';
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { view } from '@shuvi/app/core/platform';
|
|
6
|
+
import * as server from '@shuvi/app/user/server';
|
|
7
|
+
import * as application from '../../app/server';
|
|
8
|
+
export { pageRoutes, apiRoutes, middlewareRoutes, server, view, application };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { IApplication } from '@shuvi/platform-shared/shared';
|
|
3
|
-
export default function AppContainer({
|
|
3
|
+
export default function AppContainer({ app, children }: React.PropsWithChildren<{
|
|
4
4
|
app: IApplication;
|
|
5
|
-
|
|
6
|
-
}): JSX.Element;
|
|
5
|
+
}>): JSX.Element;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { errorModel } from '@shuvi/platform-shared/shared';
|
|
3
|
-
import { createContainer } from '@shuvi/redox-react';
|
|
4
3
|
import { AppProvider } from './applicationContext';
|
|
5
4
|
import ErrorPage from './ErrorPage';
|
|
6
5
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
7
|
-
|
|
6
|
+
import { Provider, useSharedModel } from './store';
|
|
8
7
|
function ErrorGuard({ children = null }) {
|
|
9
8
|
const [errorState] = useSharedModel(errorModel);
|
|
10
9
|
if (errorState.error !== undefined) {
|
|
@@ -12,10 +11,10 @@ function ErrorGuard({ children = null }) {
|
|
|
12
11
|
}
|
|
13
12
|
return <>{children}</>;
|
|
14
13
|
}
|
|
15
|
-
export default function AppContainer({
|
|
14
|
+
export default function AppContainer({ app, children }) {
|
|
16
15
|
return (<ErrorBoundary>
|
|
17
16
|
<AppProvider app={app}>
|
|
18
|
-
<Provider storeManager={app.
|
|
17
|
+
<Provider storeManager={app.store}>
|
|
19
18
|
<ErrorGuard>{children}</ErrorGuard>
|
|
20
19
|
</Provider>
|
|
21
20
|
</AppProvider>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { IPageRouteRecord
|
|
2
|
-
export default function getRoutes(routes:
|
|
1
|
+
import { IPageRouteRecord } from '@shuvi/platform-shared/shared';
|
|
2
|
+
export default function getRoutes(routes: IPageRouteRecord[]): IPageRouteRecord[];
|
|
@@ -13,18 +13,17 @@ import { loadRouteComponent } from './loadRouteComponent';
|
|
|
13
13
|
export default function getRoutes(routes) {
|
|
14
14
|
const getRoutesWithRequire = (routes) => routes.map(x => {
|
|
15
15
|
const originalRoute = Object.assign({}, x);
|
|
16
|
-
const {
|
|
16
|
+
const { __componentRawRequest__, __import__, __resolveWeak__, children } = originalRoute, rest = __rest(originalRoute, ["__componentRawRequest__", "__import__", "__resolveWeak__", "children"]);
|
|
17
17
|
const route = Object.assign({}, rest);
|
|
18
18
|
if (children) {
|
|
19
19
|
route.children = getRoutesWithRequire(children);
|
|
20
20
|
}
|
|
21
|
-
if (
|
|
22
|
-
route.component = loadRouteComponent(__import__, {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
21
|
+
if (__import__) {
|
|
22
|
+
route.component = loadRouteComponent(__import__, Object.assign({ webpack: __resolveWeak__ }, (__componentRawRequest__ && {
|
|
23
|
+
modules: [__componentRawRequest__]
|
|
24
|
+
})));
|
|
26
25
|
}
|
|
27
|
-
return Object.assign({
|
|
26
|
+
return Object.assign({ __componentRawRequest__, __resolveWeak__ }, route);
|
|
28
27
|
});
|
|
29
28
|
const routesWithRequire = getRoutesWithRequire(routes || []);
|
|
30
29
|
return routesWithRequire;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { IStoreManager } from '@shuvi/redox';
|
|
3
3
|
export declare const RedoxWrapper: (App: any, appContext: {
|
|
4
|
-
|
|
4
|
+
store: IStoreManager;
|
|
5
5
|
}) => {
|
|
6
|
-
(
|
|
6
|
+
(): JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { RedoxRoot } from '@shuvi/redox-react';
|
|
3
3
|
export const RedoxWrapper = (App, appContext) => {
|
|
4
|
-
function RedoxAppWrapper(
|
|
5
|
-
return (<RedoxRoot storeManager={appContext.
|
|
6
|
-
<App
|
|
4
|
+
function RedoxAppWrapper() {
|
|
5
|
+
return (<RedoxRoot storeManager={appContext.store}>
|
|
6
|
+
<App />
|
|
7
7
|
</RedoxRoot>);
|
|
8
8
|
}
|
|
9
9
|
RedoxAppWrapper.displayName = 'RedoxAppWrapper';
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { IStoreManager } from '@shuvi/redox';
|
|
2
|
+
declare module '@shuvi/runtime' {
|
|
3
|
+
interface CustomAppContext {
|
|
4
|
+
store: IStoreManager;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
declare const _default: import("@shuvi/platform-shared/shared").IPluginInstance<import("@shuvi/platform-shared/shared").BuiltInRuntimePluginHooks & import("@shuvi/runtime").CustomRuntimePluginHooks, void>;
|
|
2
8
|
export default _default;
|
|
@@ -11,6 +11,8 @@ import { createRuntimePlugin } from '@shuvi/platform-shared/shared';
|
|
|
11
11
|
import { RedoxWrapper } from './RedoxWrapper';
|
|
12
12
|
export default createRuntimePlugin({
|
|
13
13
|
appComponent: (App, appContext) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
-
return RedoxWrapper(App,
|
|
14
|
+
return RedoxWrapper(App, {
|
|
15
|
+
store: appContext.store
|
|
16
|
+
});
|
|
15
17
|
})
|
|
16
18
|
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
declare const Provider: (props: import("react").PropsWithChildren<{
|
|
3
|
+
storeManager?: import("@shuvi/redox").IStoreManager | undefined;
|
|
4
|
+
}>) => JSX.Element, useSharedModel: import("@shuvi/redox-react/esm/types").IUseModel;
|
|
5
|
+
export { Provider, useSharedModel };
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import { IAppState } from '@shuvi/platform-shared/shared';
|
|
2
1
|
import { IHtmlTag, IViewClient, IViewServer } from '../../shared';
|
|
3
2
|
export { IHtmlTag };
|
|
4
3
|
export declare type IReactAppData = {
|
|
5
|
-
appProps?: Record<string, any>;
|
|
6
|
-
errorProps?: {
|
|
7
|
-
notFound: boolean;
|
|
8
|
-
};
|
|
9
4
|
dynamicIds?: Array<string | number>;
|
|
10
|
-
appState?: IAppState;
|
|
11
|
-
loadersData: any;
|
|
12
5
|
};
|
|
13
6
|
export declare type IReactServerView = IViewServer<IReactAppData>;
|
|
14
7
|
export declare type IReactClientView = IViewClient<IReactAppData>;
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
import { useMatchedRoute } from '@shuvi/router-react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { loaderModel } from '@shuvi/platform-shared/shared';
|
|
3
|
+
import { useSharedModel } from './store';
|
|
4
4
|
export const noLoaderMessage = 'Warning: no loader found. Please make sure the page component where `useLoaderData` is called has a `loader` export.';
|
|
5
5
|
export const useLoaderData = () => {
|
|
6
|
-
var _a;
|
|
7
6
|
const currentMatch = useMatchedRoute();
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const id = currentMatch.route.id;
|
|
8
|
+
const [loader] = useSharedModel(loaderModel, s => {
|
|
9
|
+
return {
|
|
10
|
+
hasLoader: Object.prototype.hasOwnProperty.call(s.dataByRouteId, id),
|
|
11
|
+
data: s.dataByRouteId[id]
|
|
12
|
+
};
|
|
13
|
+
}, [id]);
|
|
14
|
+
if (!loader.hasLoader) {
|
|
12
15
|
throw Error(noLoaderMessage);
|
|
13
16
|
}
|
|
14
|
-
|
|
15
|
-
const [_, forceUpdate] = useReducer(state => state * -1, 1);
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
const cancel = loaderManager.subscribe(() => {
|
|
18
|
-
const newData = loaderManager.getData(id);
|
|
19
|
-
if (newData !== data) {
|
|
20
|
-
dataRef.current = newData;
|
|
21
|
-
forceUpdate();
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
return cancel;
|
|
25
|
-
}, []);
|
|
26
|
-
return dataRef.current;
|
|
17
|
+
return loader.data;
|
|
27
18
|
};
|
|
@@ -20,8 +20,8 @@ export class ReactClientView {
|
|
|
20
20
|
this._isInitialRender = true;
|
|
21
21
|
this.renderApp = ({ appContainer, app, appData }) => __awaiter(this, void 0, void 0, function* () {
|
|
22
22
|
const { _isInitialRender: isInitialRender } = this;
|
|
23
|
-
const { router, appComponent: AppComponent,
|
|
24
|
-
let { ssr,
|
|
23
|
+
const { router, appComponent: AppComponent, setError: setAppError } = app;
|
|
24
|
+
let { ssr, dynamicIds } = appData;
|
|
25
25
|
// For e2e test
|
|
26
26
|
if (window.__SHUVI) {
|
|
27
27
|
window.__SHUVI.router = router;
|
|
@@ -39,13 +39,13 @@ export class ReactClientView {
|
|
|
39
39
|
const { matches } = router.current;
|
|
40
40
|
if (!matches.length) {
|
|
41
41
|
// no handler no matches
|
|
42
|
-
|
|
42
|
+
setAppError(SHUVI_ERROR.PAGE_NOT_FOUND);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
const root = (<Router router={router}>
|
|
46
46
|
<AppContainer app={app}>
|
|
47
47
|
<HeadManagerContext.Provider value={headManager.updateHead}>
|
|
48
|
-
<TypedAppComponent
|
|
48
|
+
<TypedAppComponent />
|
|
49
49
|
</HeadManagerContext.Provider>
|
|
50
50
|
</AppContainer>
|
|
51
51
|
</Router>);
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import * as React from 'react';
|
|
11
11
|
import { renderToString } from 'react-dom/server';
|
|
12
|
-
import {
|
|
12
|
+
import { redirect } from '@shuvi/platform-shared/shared';
|
|
13
13
|
import { SHUVI_ERROR } from '@shuvi/shared/lib/constants';
|
|
14
14
|
import { Router } from '@shuvi/router-react';
|
|
15
15
|
import Loadable, { LoadableContext } from '../loadable';
|
|
@@ -19,20 +19,17 @@ export class ReactServerView {
|
|
|
19
19
|
constructor() {
|
|
20
20
|
this.renderApp = ({ app, manifest, getAssetPublicUrl }) => __awaiter(this, void 0, void 0, function* () {
|
|
21
21
|
yield Loadable.preloadAll();
|
|
22
|
-
const {
|
|
22
|
+
const { router, appComponent: AppComponent, setError: setAppError } = app;
|
|
23
23
|
yield router.ready;
|
|
24
24
|
// todo: move these into renderer
|
|
25
25
|
let { pathname, matches, redirected } = router.current;
|
|
26
26
|
// handler no matches
|
|
27
27
|
if (!matches.length) {
|
|
28
|
-
|
|
28
|
+
setAppError(SHUVI_ERROR.PAGE_NOT_FOUND);
|
|
29
29
|
}
|
|
30
30
|
if (redirected) {
|
|
31
31
|
return redirect(pathname);
|
|
32
32
|
}
|
|
33
|
-
// todo: move loader into app, avoid using global module
|
|
34
|
-
const loaderManager = getLoaderManager();
|
|
35
|
-
const loadersData = yield loaderManager.getAllData();
|
|
36
33
|
const loadableModules = [];
|
|
37
34
|
let htmlContent;
|
|
38
35
|
let head;
|
|
@@ -47,7 +44,6 @@ export class ReactServerView {
|
|
|
47
44
|
htmlContent = renderToString(RootApp);
|
|
48
45
|
}
|
|
49
46
|
finally {
|
|
50
|
-
loaderManager.clearAllData();
|
|
51
47
|
head = Head.rewind() || [];
|
|
52
48
|
}
|
|
53
49
|
const { loadble } = manifest;
|
|
@@ -88,13 +84,11 @@ export class ReactServerView {
|
|
|
88
84
|
}
|
|
89
85
|
}
|
|
90
86
|
const appData = {
|
|
91
|
-
dynamicIds: [...dynamicImportIdSet]
|
|
92
|
-
loadersData
|
|
87
|
+
dynamicIds: [...dynamicImportIdSet]
|
|
93
88
|
};
|
|
94
89
|
if (dynamicImportIdSet.size) {
|
|
95
90
|
appData.dynamicIds = Array.from(dynamicImportIdSet);
|
|
96
91
|
}
|
|
97
|
-
appData.appState = storeManager.getState();
|
|
98
92
|
return {
|
|
99
93
|
appData,
|
|
100
94
|
content: htmlContent,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// exported by @shuvi/
|
|
1
|
+
// exported by @shuvi/runtime
|
|
2
2
|
export {};
|
|
@@ -13,7 +13,7 @@ declare const _default: {
|
|
|
13
13
|
configWebpack: import("@shuvi/hook").AsyncSeriesWaterfallHook<import("@shuvi/service/lib/core/lifecycleTypes").WebpackChainType, import("@shuvi/service/lib/core/lifecycleTypes").ConfigWebpackAssistant>;
|
|
14
14
|
addExtraTarget: import("@shuvi/hook").AsyncParallelHook<import("@shuvi/service/lib/core/lifecycleTypes").ExtraTargetAssistant, void, import("@shuvi/service/lib/core/lifecycleTypes").TargetChain>;
|
|
15
15
|
addResource: import("@shuvi/hook").AsyncParallelHook<void, void, import("@shuvi/service/lib/core/lifecycleTypes").Resources | import("@shuvi/service/lib/core/lifecycleTypes").Resources[]>;
|
|
16
|
-
addRuntimeFile: import("@shuvi/hook").AsyncParallelHook<void, import("@shuvi/service/lib/core/lifecycleTypes").AddRuntimeFileUtils, import("@shuvi/service/lib/project/index").
|
|
16
|
+
addRuntimeFile: import("@shuvi/hook").AsyncParallelHook<void, import("@shuvi/service/lib/core/lifecycleTypes").AddRuntimeFileUtils, import("@shuvi/service/lib/project/index").FileOption<any, any> | import("@shuvi/service/lib/project/index").FileOption<any, any>[]>;
|
|
17
17
|
addRuntimeService: import("@shuvi/hook").AsyncParallelHook<void, void, import("@shuvi/service/lib/core/lifecycleTypes").RuntimeService | import("@shuvi/service/lib/core/lifecycleTypes").RuntimeService[]>;
|
|
18
18
|
} & import("@shuvi/service/lib/core/apiTypes").CustomCorePluginHooks, import("@shuvi/service").IPluginContext>;
|
|
19
19
|
};
|
|
@@ -50,9 +50,18 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
50
50
|
setup: ({ addHooks }) => {
|
|
51
51
|
addHooks({ addRoutes: hooks_1.addRoutes, addMiddlewareRoutes: hooks_1.addMiddlewareRoutes });
|
|
52
52
|
},
|
|
53
|
-
addRuntimeFile: ({ defineFile }, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
53
|
+
addRuntimeFile: ({ defineFile, getContent }, context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
54
|
const { config: { routes: pageRoutes, middlewareRoutes, apiRoutes, conventionRoutes }, paths, pluginRunner, phase } = context;
|
|
55
55
|
const isBuildPhase = phase === 'PHASE_PRODUCTION_BUILD';
|
|
56
|
+
const rawRoutes = defineFile({
|
|
57
|
+
name: 'virtual-raw-routes.js',
|
|
58
|
+
virtual: true,
|
|
59
|
+
content: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
|
+
const rawRoutes = yield (0, node_1.getRawRoutesFromDir)(paths.routesDir, conventionRoutes.exclude);
|
|
61
|
+
return rawRoutes;
|
|
62
|
+
}),
|
|
63
|
+
dependencies: [paths.routesDir]
|
|
64
|
+
});
|
|
56
65
|
const pageRoutesFile = defineFile({
|
|
57
66
|
name: 'routes.js',
|
|
58
67
|
content: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -62,7 +71,7 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
62
71
|
routes = pageRoutes;
|
|
63
72
|
}
|
|
64
73
|
else {
|
|
65
|
-
const { routes: _routes, warnings } = yield (0, node_1.getPageRoutes)(
|
|
74
|
+
const { routes: _routes, warnings } = yield (0, node_1.getPageRoutes)(getContent(rawRoutes), conventionRoutes.exclude);
|
|
66
75
|
if (isBuildPhase) {
|
|
67
76
|
warnings.forEach(warning => {
|
|
68
77
|
console.warn(warning.msg);
|
|
@@ -77,7 +86,7 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
77
86
|
(0, page_1.setRoutes)(normalizedRoutes);
|
|
78
87
|
return (0, page_1.generateRoutesContent)(normalizedRoutes);
|
|
79
88
|
}),
|
|
80
|
-
dependencies: [
|
|
89
|
+
dependencies: [rawRoutes]
|
|
81
90
|
});
|
|
82
91
|
const apiRoutesFile = defineFile({
|
|
83
92
|
name: 'apiRoutes.js',
|
|
@@ -88,7 +97,7 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
88
97
|
routes = apiRoutes;
|
|
89
98
|
}
|
|
90
99
|
else {
|
|
91
|
-
const { routes: _routes, warnings } = yield (0, node_1.getApiRoutes)(
|
|
100
|
+
const { routes: _routes, warnings } = yield (0, node_1.getApiRoutes)(getContent(rawRoutes), conventionRoutes.exclude);
|
|
92
101
|
if (isBuildPhase) {
|
|
93
102
|
warnings.forEach(warning => {
|
|
94
103
|
console.warn(warning);
|
|
@@ -98,7 +107,7 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
98
107
|
}
|
|
99
108
|
return (0, api_1.generateRoutesContent)(routes, paths.routesDir);
|
|
100
109
|
}),
|
|
101
|
-
dependencies: [
|
|
110
|
+
dependencies: [rawRoutes]
|
|
102
111
|
});
|
|
103
112
|
const middlewareRoutesFile = defineFile({
|
|
104
113
|
name: 'middlewareRoutes.js',
|
|
@@ -109,7 +118,7 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
109
118
|
routes = middlewareRoutes;
|
|
110
119
|
}
|
|
111
120
|
else {
|
|
112
|
-
const { routes: _routes, warnings } = yield (0, node_1.getMiddlewareRoutes)(
|
|
121
|
+
const { routes: _routes, warnings } = yield (0, node_1.getMiddlewareRoutes)(getContent(rawRoutes), conventionRoutes.exclude);
|
|
113
122
|
if (isBuildPhase) {
|
|
114
123
|
warnings.forEach(warning => {
|
|
115
124
|
console.warn(warning);
|
|
@@ -122,7 +131,7 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
122
131
|
baseDir: paths.routesDir
|
|
123
132
|
});
|
|
124
133
|
}),
|
|
125
|
-
dependencies: [
|
|
134
|
+
dependencies: [rawRoutes]
|
|
126
135
|
});
|
|
127
136
|
const loadersFile = defineFile({
|
|
128
137
|
name: 'loaders.js',
|
|
@@ -167,6 +176,7 @@ const plugin = (0, service_1.createPlugin)({
|
|
|
167
176
|
dependencies: [loadersFile]
|
|
168
177
|
});
|
|
169
178
|
return [
|
|
179
|
+
rawRoutes,
|
|
170
180
|
pageRoutesFile,
|
|
171
181
|
apiRoutesFile,
|
|
172
182
|
middlewareRoutesFile,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IPageRouteConfig, IPageRouteConfigWithId } from '@shuvi/platform-shared/shared';
|
|
2
2
|
export { IPageRouteConfig };
|
|
3
3
|
/**
|
|
4
|
-
* returns JSON string of
|
|
4
|
+
* returns JSON string of IPageRouteConfigWithId
|
|
5
5
|
*/
|
|
6
|
-
export declare function serializeRoutes(routes: IPageRouteConfigWithId[]): string;
|
|
6
|
+
export declare function serializeRoutes(routes: IPageRouteConfigWithId[], isServer: boolean): string;
|
|
7
7
|
export declare function normalizeRoutes(routes: IPageRouteConfig[], componentDir: string, parentPath?: string): IPageRouteConfigWithId[];
|
|
8
8
|
export declare const generateRoutesContent: (routes: IPageRouteConfigWithId[]) => string;
|
|
@@ -10,18 +10,23 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
}
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
13
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
17
|
exports.generateRoutesContent = exports.normalizeRoutes = exports.serializeRoutes = void 0;
|
|
15
18
|
const crypto_1 = require("crypto");
|
|
19
|
+
const querystring_1 = __importDefault(require("querystring"));
|
|
16
20
|
const constants_1 = require("@shuvi/shared/lib/constants");
|
|
17
21
|
const file_1 = require("@shuvi/utils/lib/file");
|
|
18
22
|
function genRouteId(filepath) {
|
|
19
23
|
return (0, crypto_1.createHash)('md4').update(filepath).digest('hex').substr(0, 4);
|
|
20
24
|
}
|
|
25
|
+
const KEEP_SYMBOL = querystring_1.default.stringify({ keep: ['default'] });
|
|
21
26
|
/**
|
|
22
|
-
* returns JSON string of
|
|
27
|
+
* returns JSON string of IPageRouteConfigWithId
|
|
23
28
|
*/
|
|
24
|
-
function serializeRoutes(routes) {
|
|
29
|
+
function serializeRoutes(routes, isServer) {
|
|
25
30
|
let res = '';
|
|
26
31
|
for (let index = 0; index < routes.length; index++) {
|
|
27
32
|
const _a = routes[index], { children: childRoutes } = _a, route = __rest(_a, ["children"]);
|
|
@@ -33,16 +38,18 @@ function serializeRoutes(routes) {
|
|
|
33
38
|
if (key === 'component') {
|
|
34
39
|
const { component } = route;
|
|
35
40
|
const componentSource = component;
|
|
36
|
-
const
|
|
41
|
+
const componentRequest = `${componentSource}?${constants_1.ROUTE_RESOURCE_QUERYSTRING}&${KEEP_SYMBOL}`;
|
|
37
42
|
// `webpackExports` works with production and optimization.minimize, check compiled dist
|
|
38
|
-
|
|
39
|
-
`
|
|
40
|
-
__componentSource__: "${componentSource}"
|
|
43
|
+
if (isServer) {
|
|
44
|
+
strRoute += `__componentRawRequest__: "${componentRequest}",\n`;
|
|
45
|
+
strRoute += `__componentSource__: "${componentSource}",\n`;
|
|
46
|
+
}
|
|
47
|
+
strRoute += `
|
|
41
48
|
__import__: () => import(
|
|
42
49
|
/* webpackChunkName: "page-${id}" */
|
|
43
50
|
/* webpackExports: "default" */
|
|
44
|
-
"${
|
|
45
|
-
__resolveWeak__: () => [require.resolveWeak("${
|
|
51
|
+
"${componentRequest}"),
|
|
52
|
+
__resolveWeak__: () => [require.resolveWeak("${componentRequest}")]`.trim();
|
|
46
53
|
}
|
|
47
54
|
else {
|
|
48
55
|
strRoute += `${key}: ${JSON.stringify(route[key])}`;
|
|
@@ -50,7 +57,7 @@ __resolveWeak__: () => [require.resolveWeak("${componentSourceWithAffix}")]`.tri
|
|
|
50
57
|
strRoute += `,\n`;
|
|
51
58
|
}
|
|
52
59
|
if (childRoutes && childRoutes.length > 0) {
|
|
53
|
-
strRoute += `children: ${serializeRoutes(childRoutes)},\n`;
|
|
60
|
+
strRoute += `children: ${serializeRoutes(childRoutes, isServer)},\n`;
|
|
54
61
|
}
|
|
55
62
|
res += `{${strRoute}},\n`;
|
|
56
63
|
}
|
|
@@ -77,7 +84,18 @@ function normalizeRoutes(routes, componentDir, parentPath = '') {
|
|
|
77
84
|
}
|
|
78
85
|
exports.normalizeRoutes = normalizeRoutes;
|
|
79
86
|
const generateRoutesContent = (routes) => {
|
|
80
|
-
const
|
|
81
|
-
|
|
87
|
+
const serverRoutes = serializeRoutes(routes, true);
|
|
88
|
+
const clientRoutes = serializeRoutes(routes, false);
|
|
89
|
+
return `
|
|
90
|
+
let routes;
|
|
91
|
+
|
|
92
|
+
if (typeof windows === 'undefined') {
|
|
93
|
+
routes = ${serverRoutes}
|
|
94
|
+
} else {
|
|
95
|
+
routes = ${clientRoutes}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default routes
|
|
99
|
+
`;
|
|
82
100
|
};
|
|
83
101
|
exports.generateRoutesContent = generateRoutesContent;
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
+
import { IPlatformContext, ResolvedPlugin } from '@shuvi/service/lib/core';
|
|
1
2
|
export { getPageMiddleware, IHtmlDocument, ITemplateData, IViewServer, IViewClient } from './lib';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
extendConfig: import("@shuvi/hook").SyncWaterfallHook<import("@shuvi/service").Config, void>;
|
|
5
|
-
afterInit: import("@shuvi/hook").AsyncParallelHook<void, void, void>;
|
|
6
|
-
afterBuild: import("@shuvi/hook").AsyncParallelHook<void, void, void>;
|
|
7
|
-
afterDestroy: import("@shuvi/hook").AsyncParallelHook<void, void, void>;
|
|
8
|
-
afterBundlerDone: import("@shuvi/hook").AsyncParallelHook<import("@shuvi/service/lib/core/lifecycleTypes").BundlerDoneExtra, void, void>;
|
|
9
|
-
afterBundlerTargetDone: import("@shuvi/hook").AsyncParallelHook<import("@shuvi/service/lib/core/lifecycleTypes").BundlerTargetDoneExtra, void, void>;
|
|
10
|
-
configWebpack: import("@shuvi/hook").AsyncSeriesWaterfallHook<import("@shuvi/service/lib/core/lifecycleTypes").WebpackChainType, import("@shuvi/service/lib/core/lifecycleTypes").ConfigWebpackAssistant>;
|
|
11
|
-
addExtraTarget: import("@shuvi/hook").AsyncParallelHook<import("@shuvi/service/lib/core/lifecycleTypes").ExtraTargetAssistant, void, import("@shuvi/service/lib/core/lifecycleTypes").TargetChain>;
|
|
12
|
-
addResource: import("@shuvi/hook").AsyncParallelHook<void, void, import("@shuvi/service/lib/core/lifecycleTypes").Resources | import("@shuvi/service/lib/core/lifecycleTypes").Resources[]>;
|
|
13
|
-
addRuntimeFile: import("@shuvi/hook").AsyncParallelHook<void, import("@shuvi/service/lib/core/lifecycleTypes").AddRuntimeFileUtils, import("@shuvi/service/lib/project/index").FileOptions<any, any> | import("@shuvi/service/lib/project/index").FileOptions<any, any>[]>;
|
|
14
|
-
addRuntimeService: import("@shuvi/hook").AsyncParallelHook<void, void, import("@shuvi/service/lib/core/lifecycleTypes").RuntimeService | import("@shuvi/service/lib/core/lifecycleTypes").RuntimeService[]>;
|
|
15
|
-
} & import("@shuvi/service/lib/core/apiTypes").CustomCorePluginHooks, import("@shuvi/service").IPluginContext>;
|
|
16
|
-
server: import("@shuvi/hook").IPluginInstance<import("@shuvi/service/lib/server/plugin").BuiltInServerPluginHooks & import("@shuvi/service/lib/server/pluginTypes").CustomServerPluginHooks, import("@shuvi/service").IServerPluginContext>;
|
|
17
|
-
types: string;
|
|
18
|
-
};
|
|
19
|
-
export default _default;
|
|
3
|
+
/** This plugin uses `platformContext` so that it is set to a plugin getter */
|
|
4
|
+
export declare const getPlugin: (platformContext: IPlatformContext) => ResolvedPlugin;
|