Skip to content

Commit

Permalink
feat: ssr mode add config useStream (#12779)
Browse files Browse the repository at this point in the history
* fix: ssr disable suspence

* fix: hydrate also need to diable suspence
  • Loading branch information
Jinbao1001 authored Nov 14, 2024
1 parent 874f7c5 commit ae0ddc5
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 34 deletions.
14 changes: 1 addition & 13 deletions examples/ssr-demo/.umirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,8 @@ export default {
clientLoader: {},
ssr: {},
exportStatic: {},
// mako: {},
// mako: {
// plugins: [
// {
// load: () => {},
// },
// ],
// },
// ssr: {
// // builder: 'mako',
// },
// exportStatic: {},
styles: [`body { color: red; }`],

// mako: {},
metas: [
{
name: 'test',
Expand Down
3 changes: 1 addition & 2 deletions examples/ssr-demo/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import styles from './index.less';
// @ts-ignore
import umiLogo from './umi.png';
// @ts-ignore
import styles1 from './a.module.css';

export default function HomePage() {
const clientLoaderData = useClientLoaderData();
Expand All @@ -42,7 +41,7 @@ export default function HomePage() {

return (
<div>
<h1 className={styles1.b}>Hello~1</h1>
<h1 className={styles.b}>Hello~1</h1>
<p className="server_inserted_style">id: {id}</p>
<p className={styles.blue}>This is index.tsx</p>
<p className={cssStyle.title}>I should be pink</p>
Expand Down
1 change: 1 addition & 0 deletions packages/preset-umi/src/features/ssr/ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default (api: IApi) => {
pureApp: zod.boolean(),
pureHtml: zod.boolean(),
}),
useStream: zod.boolean().default(true),
})
.deepPartial();
},
Expand Down
7 changes: 5 additions & 2 deletions packages/preset-umi/src/features/tmpFiles/tmpFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ declare module '*.txt' {
}),
).join('\n');

const ssrConfig = api.config.ssr;
const __INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = api.config.ssr
?.__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? {
pureApp: false,
Expand Down Expand Up @@ -331,7 +332,8 @@ declare module '*.txt' {
__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: JSON.stringify(
__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
),
hydrate: !!api.config.ssr,
hydrate: !!ssrConfig,
useStream: ssrConfig?.useStream ?? true,
reactRouter5Compat: !!api.config.reactRouter5Compat,
loadingComponent: api.appData.globalLoading,
},
Expand Down Expand Up @@ -506,7 +508,7 @@ if (process.env.NODE_ENV === 'development') {
});

// umi.server.ts
if (api.config.ssr) {
if (ssrConfig) {
const umiPluginPath = winPath(join(umiDir, 'client/client/plugin.js'));
const umiServerPath = winPath(require.resolve('@umijs/server/dist/ssr'));

Expand Down Expand Up @@ -563,6 +565,7 @@ if (process.env.NODE_ENV === 'development') {
),
mountElementId,
basename: api.config.base,
useStream: ssrConfig?.useStream ?? true,
},
});
}
Expand Down
3 changes: 2 additions & 1 deletion packages/preset-umi/templates/server.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ const createOpts = {
htmlPageOpts: {{{htmlPageOpts}}},
__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {{{__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED}}},
mountElementId: '{{{mountElementId}}}',
basename: '{{{basename}}}'
basename: '{{{basename}}}',
useStream: {{{useStream}}}
};
const requestHandler = createRequestHandler(createOpts);
/**
Expand Down
1 change: 1 addition & 0 deletions packages/preset-umi/templates/umi.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ async function render() {
{{#hydrate}}
hydrate: true,
{{/hydrate}}
useStream: {{{useStream}}},
{{#reactRouter5Compat}}
reactRouter5Compat: true,
{{/reactRouter5Compat}}
Expand Down
6 changes: 6 additions & 0 deletions packages/renderer-react/src/browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ export type RenderClientOpts = {
*/
hydrate?: boolean;

/**
* ssr 是否启用流式渲染, 默认 true, 对 SEO 存在一定的负优化
*/
useStream?: boolean;

/**
* 直接返回组件,是为了方便测试
*/
Expand Down Expand Up @@ -188,6 +193,7 @@ const getBrowser = (
routeComponents: opts.routeComponents,
loadingComponent: opts.loadingComponent,
reactRouter5Compat: opts.reactRouter5Compat,
useStream: opts.useStream,
});
opts.pluginManager.applyPlugins({
key: 'patchClientRoutes',
Expand Down
40 changes: 25 additions & 15 deletions packages/renderer-react/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ export function createClientRoutes(opts: {
parentId?: string;
loadingComponent?: React.ReactNode;
reactRouter5Compat?: boolean;
useStream?: boolean;
}) {
const { routesById, parentId, routeComponents } = opts;
const { routesById, parentId, routeComponents, useStream = true } = opts;
return Object.keys(routesById)
.filter((id) => routesById[id].parentId === parentId)
.map((id) => {
Expand All @@ -34,13 +35,15 @@ export function createClientRoutes(opts: {
(rid) => routesById[rid].parentId === id,
).length > 0,
}),
useStream,
});
const children = createClientRoutes({
routesById,
routeComponents,
parentId: route.id,
loadingComponent: opts.loadingComponent,
reactRouter5Compat: opts.reactRouter5Compat,
useStream,
});
if (children.length > 0) {
route.children = children;
Expand Down Expand Up @@ -74,8 +77,9 @@ function createClientRoute(opts: {
loadingComponent?: React.ReactNode;
hasChildren?: boolean;
reactRouter5Compat?: boolean;
useStream?: boolean;
}): IClientRoute {
const { route } = opts;
const { route, useStream = true } = opts;
const { redirect, ...props } = route;
const Remote = opts.reactRouter5Compat
? RemoteComponentReactRouter5
Expand All @@ -93,6 +97,7 @@ function createClientRoute(opts: {
loader={React.memo(opts.routeComponent)}
loadingComponent={opts.loadingComponent || DefaultLoading}
hasChildren={opts.hasChildren}
useStream={useStream}
/>
</RouteContext.Provider>
),
Expand All @@ -117,28 +122,33 @@ function RemoteComponentReactRouter5(props: any) {

// staticContext 没有兼容 好像没看到对应的兼容写法
const Component = props.loader;

return (
const ComponentProps = {
location: history.location,
match,
history,
params,
route,
routes: clientRoutes,
};
const Remote = () => (
<Component {...ComponentProps}>{props.hasChildren && <Outlet />}</Component>
);
return props.useStream ? (
<React.Suspense fallback={<props.loadingComponent />}>
<Component
location={history.location}
match={match}
history={history}
params={params}
route={route}
routes={clientRoutes}
>
{props.hasChildren && <Outlet />}
</Component>
<Remote />
</React.Suspense>
) : (
<Remote />
);
}

function RemoteComponent(props: any) {
const Component = props.loader;
return (
return props.useStream ? (
<React.Suspense fallback={<props.loadingComponent />}>
<Component />
</React.Suspense>
) : (
<Component />
);
}
1 change: 1 addition & 0 deletions packages/renderer-react/src/server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export async function getClientRootComponent(opts: IRootComponentOptions) {
const clientRoutes = createClientRoutes({
routesById: opts.routes,
routeComponents: components,
useStream: opts.useStream,
});

opts.pluginManager.applyPlugins({
Expand Down
1 change: 1 addition & 0 deletions packages/renderer-react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export interface IRootComponentOptions extends IHtmlHydrateOptions {
loaderData: { [routeKey: string]: any };
manifest: any;
basename?: string;
useStream?: boolean;
}

export interface IHtmlProps extends IHtmlHydrateOptions {
Expand Down
4 changes: 3 additions & 1 deletion packages/server/src/ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ interface CreateRequestHandlerOptions extends CreateRequestServerlessOptions {
};
mountElementId: string;
basename?: string;
useStream?: boolean;
}

interface IExecLoaderOpts {
Expand Down Expand Up @@ -173,6 +174,7 @@ function createJSXGenerator(opts: CreateRequestHandlerOptions) {
opts.__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
mountElementId: opts.mountElementId,
basename,
useStream: opts.useStream,
};
const element = (await opts.getClientRootComponent(
context,
Expand Down Expand Up @@ -229,7 +231,7 @@ export function createMarkupGenerator(opts: CreateRequestHandlerOptions) {
next();
};
writable.on('finish', async () => {
let html = Buffer.concat(chunks).toString('utf8');
let html = Buffer.concat(chunks as any).toString('utf8');
const serverHTML = getGenerateStaticHTML(serverInsertedHTMLCallbacks);
if (serverHTML) {
html = html.replace(/<\/head>/, `${serverHTML}</head>`);
Expand Down

0 comments on commit ae0ddc5

Please sign in to comment.