Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR 的 getManifest()支持req时传入sourceDir表示SSR产物目录 #11715

Merged
merged 13 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions packages/preset-umi/templates/server.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ export function getValidKeys() {
return [{{#validKeys}}'{{{ . }}}',{{/validKeys}}];
}

export function getManifest() {
export function getManifest(sourceDir) {
return JSON.parse(require('fs').readFileSync(
process.env.SSR_RESOURCE_DIR ? process.env.SSR_RESOURCE_DIR + '/build-manifest.json' :
'{{{ assetsPath }}}', 'utf-8'));
sourceDir ? require('path').join(sourceDir,'build-manifest.json') : '{{{ assetsPath }}}', 'utf-8'));
}

export function createHistory(opts) {
Expand All @@ -41,15 +40,14 @@ global.g_getAssets = (fileName) => {
let m = typeof manifest === 'function' ? manifest() : manifest;
return m.assets[fileName];
};

const manifest = {{{ env }}} === 'development' ? getManifest : getManifest();
const createOpts = {
routesWithServerLoader,
PluginManager,
getPlugins,
getValidKeys,
getRoutes,
manifest,
manifest: getManifest,
getClientRootComponent,
helmetContext,
createHistory,
Expand Down
39 changes: 16 additions & 23 deletions packages/server/src/ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface CreateRequestHandlerOptions {
routesWithServerLoader: RouteLoaders;
PluginManager: any;
manifest:
| (() => { assets: Record<string, string> })
| ((sourceDir?: string) => { assets: Record<string, string> })
| { assets: Record<string, string> };
getPlugins: () => any;
getValidKeys: () => any;
Expand All @@ -24,6 +24,7 @@ interface CreateRequestHandlerOptions {
helmetContext?: any;
ServerInsertedHTMLContext: React.Context<ServerInsertedHTMLHook | null>;
withoutHTML?: boolean;
sourceDir?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看起来这里需要注释注明一下 sourceDir 是给 serverless 函数 create handler 专门用的,因为 esbuild 用到的 g_getAssets 没法传 sourceDir

global.g_getAssets = (fileName) => {
  let m = typeof manifest === 'function' ? manifest() : manifest;
  return m.assets[fileName];
};
// 生产环境这里的 manifest 就没有机会传参数了
const manifest = {{{ env }}} === 'development' ? getManifest : getManifest();

// ...
// ↓ 人工 create handler 才可以传 sourceDir
  manifest: getManifest,

Copy link
Contributor

@fz6m fz6m Oct 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interface CreateRequestHandlerServerlessOptions {
  /** 注释 */
  withoutHTML?: boolean;
  /** 注释 */
  sourceDir?: string;
}

interface CreateRequestHandlerOptions extends CreateRequestHandlerServerlessOptions {
  // ...
}

}

const createJSXProvider = (
Expand Down Expand Up @@ -55,6 +56,7 @@ function createJSXGenerator(opts: CreateRequestHandlerOptions) {
getValidKeys,
getRoutes,
createHistory,
sourceDir,
} = opts;

// make import { history } from 'umi' work
Expand Down Expand Up @@ -95,7 +97,7 @@ function createJSXGenerator(opts: CreateRequestHandlerOptions) {
);

const manifest =
typeof opts.manifest === 'function' ? opts.manifest() : opts.manifest;
typeof opts.manifest === 'function' ? opts.manifest(sourceDir) : opts.manifest;
const context = {
routes,
routeComponents,
Expand Down Expand Up @@ -237,29 +239,20 @@ export default function createRequestHandler(
};
}

// 新增的给CDN worker用的SSR请求handle
export function createUmiHandler(opts: CreateRequestHandlerOptions) {
const jsxGeneratorDeferrer = createJSXGenerator({
...opts,
withoutHTML: true,
});

return function (req: Request) {
return new Promise(async (resolve, reject) => {
const jsx = await jsxGeneratorDeferrer(new URL(req.url).pathname);

if (!jsx) {
reject(new Error('no page resource'));
return;
}

const stream = await ReactDomServer.renderToReadableStream(jsx.element, {
bootstrapScripts: [jsx.manifest.assets['umi.js'] || '/umi.js'],
onError(err: any) {
reject(err);
},
});
resolve(stream);
return async function (req: Request, params?: CreateRequestHandlerOptions) {
const jsxGeneratorDeferrer = createJSXGenerator({
...opts,
...params,
fz6m marked this conversation as resolved.
Show resolved Hide resolved
});
const jsx = await jsxGeneratorDeferrer(new URL(req.url).pathname);

if (!jsx) {
throw new Error('no page resource')
}

return ReactDomServer.renderToNodeStream(jsx.element);
};
}

Expand Down
Loading