From 0e906a1c4aaaf2046b9a92b81afa7d101c952cb6 Mon Sep 17 00:00:00 2001 From: qixuan <58852732+GiveMe-A-Name@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:03:19 +0800 Subject: [PATCH] feat: inject renderHandler to appContext & add default serverPlugins (#6012) --- .changeset/hungry-frogs-bow.md | 8 ++ packages/cli/plugin-bff/src/server.ts | 19 ++--- packages/server/core/src/plugins/default.ts | 34 +++++++++ packages/server/core/src/plugins/index.ts | 15 ++-- packages/server/core/src/plugins/monitors.ts | 7 +- .../server/core/src/plugins/render/index.ts | 70 +++--------------- .../server/core/src/plugins/render/inject.ts | 74 +++++++++++++++++++ packages/server/core/src/types/plugin.ts | 12 +++ .../server/core/tests/plugins/render.test.ts | 38 ++++++---- packages/server/prod-server/src/apply.ts | 23 ++---- packages/server/prod-server/src/types.ts | 4 +- 11 files changed, 186 insertions(+), 118 deletions(-) create mode 100644 .changeset/hungry-frogs-bow.md create mode 100644 packages/server/core/src/plugins/default.ts create mode 100644 packages/server/core/src/plugins/render/inject.ts diff --git a/.changeset/hungry-frogs-bow.md b/.changeset/hungry-frogs-bow.md new file mode 100644 index 000000000000..5c723ef425fa --- /dev/null +++ b/.changeset/hungry-frogs-bow.md @@ -0,0 +1,8 @@ +--- +'@modern-js/prod-server': patch +'@modern-js/plugin-bff': patch +'@modern-js/server-core': patch +--- + +feat: inject renderHandler to appContext & add default serverPlugins +feat: 注入 renderHandler 到 appContext & 新增默认 serverPlugins diff --git a/packages/cli/plugin-bff/src/server.ts b/packages/cli/plugin-bff/src/server.ts index 41fea2fe7d1d..c0b272449027 100644 --- a/packages/cli/plugin-bff/src/server.ts +++ b/packages/cli/plugin-bff/src/server.ts @@ -6,7 +6,7 @@ import { isWebOnly, requireExistModule, } from '@modern-js/utils'; -import { getRenderHandler, type ServerPlugin } from '@modern-js/server-core'; +import { type ServerPlugin } from '@modern-js/server-core'; import { ServerNodeMiddleware } from '@modern-js/server-core/node'; import { API_APP_NAME } from './constants'; @@ -35,7 +35,7 @@ export default (): ServerPlugin => ({ return { async prepare() { const appContext = api.useAppContext(); - const { appDirectory, distDirectory } = appContext; + const { appDirectory, distDirectory, render } = appContext; const root = isProd() ? distDirectory : appDirectory; const apiPath = path.resolve(root || process.cwd(), API_DIR); apiAppPath = path.resolve(apiPath, API_APP_NAME); @@ -57,11 +57,8 @@ export default (): ServerPlugin => ({ const enableHandleWeb = config?.bff?.enableHandleWeb; const httpMethodDecider = config?.bff?.httpMethodDecider; - const { - distDirectory: pwd, - routes, - middlewares: globalMiddlewares, - } = api.useAppContext(); + const { distDirectory: pwd, middlewares: globalMiddlewares } = + api.useAppContext(); const webOnly = await isWebOnly(); @@ -74,13 +71,7 @@ export default (): ServerPlugin => ({ }; } else { const runner = api.useHookRunners(); - const renderHandler = enableHandleWeb - ? await getRenderHandler({ - pwd, - routes: routes || [], - config, - }) - : null; + const renderHandler = enableHandleWeb ? render : null; handler = await runner.prepareApiServer( { pwd, diff --git a/packages/server/core/src/plugins/default.ts b/packages/server/core/src/plugins/default.ts new file mode 100644 index 000000000000..b494084084e3 --- /dev/null +++ b/packages/server/core/src/plugins/default.ts @@ -0,0 +1,34 @@ +import { Logger } from '@modern-js/types'; +import type { ServerPlugin } from '../types'; +import { + InjectRenderHandlerOptions, + injectRenderHandlerPlugin, +} from './render'; +import { + initMonitorsPlugin, + injectloggerPluigin, + injectServerTiming, +} from './monitors'; +import { processedByPlugin } from './processedBy'; +import { logPlugin } from './log'; +import { faviconPlugin } from './favicon'; + +export type CreateDefaultPluginsOptions = InjectRenderHandlerOptions & { + logger?: Logger; +}; + +export function createDefaultPlugins( + options: CreateDefaultPluginsOptions = {}, +) { + const plugins: ServerPlugin[] = [ + initMonitorsPlugin(), + injectRenderHandlerPlugin(options), + injectloggerPluigin(options.logger), + injectServerTiming(), + logPlugin(), + processedByPlugin(), + faviconPlugin(), + ]; + + return plugins; +} diff --git a/packages/server/core/src/plugins/index.ts b/packages/server/core/src/plugins/index.ts index a24e64c123a2..91e684b54a18 100644 --- a/packages/server/core/src/plugins/index.ts +++ b/packages/server/core/src/plugins/index.ts @@ -1,15 +1,12 @@ export { renderPlugin, + injectRenderHandlerPlugin, + type InjectRenderHandlerOptions, getRenderHandler, - type RenderPluginOptions, - type GetRenderHandlerOptions, } from './render'; export { faviconPlugin } from './favicon'; -export { processedByPlugin } from './processedBy'; -export { getLoaderCtx } from './customServer'; -export { logPlugin } from './log'; +export { injectServerTiming, injectloggerPluigin } from './monitors'; export { - initMonitorsPlugin, - injectServerTiming, - injectloggerPluigin, -} from './monitors'; + createDefaultPlugins, + type CreateDefaultPluginsOptions, +} from './default'; diff --git a/packages/server/core/src/plugins/monitors.ts b/packages/server/core/src/plugins/monitors.ts index 3e6feeabc1ec..bec7d710ed97 100644 --- a/packages/server/core/src/plugins/monitors.ts +++ b/packages/server/core/src/plugins/monitors.ts @@ -89,10 +89,11 @@ export const initMonitorsPlugin = (): ServerPlugin => ({ }, }); -export const injectloggerPluigin = (logger: Logger): ServerPlugin => ({ +export const injectloggerPluigin = (inputLogger?: Logger): ServerPlugin => ({ name: '@modern-js/inject-logger', setup(api) { + const logger = inputLogger || console; return { prepare() { const { middlewares } = api.useAppContext(); @@ -146,7 +147,7 @@ export const injectloggerPluigin = (logger: Logger): ServerPlugin => ({ }, }); -export const injectServerTiming = (metaName = 'modern-js'): ServerPlugin => ({ +export const injectServerTiming = (): ServerPlugin => ({ name: '@modern-js/inject-server-timing', setup(api) { @@ -158,7 +159,7 @@ export const injectServerTiming = (metaName = 'modern-js'): ServerPlugin => ({ return { prepare() { - const { middlewares } = api.useAppContext(); + const { middlewares, metaName } = api.useAppContext(); middlewares.push({ name: 'inject-server-timing', diff --git a/packages/server/core/src/plugins/render/index.ts b/packages/server/core/src/plugins/render/index.ts index 02c8c8df59fb..2baedf59e802 100644 --- a/packages/server/core/src/plugins/render/index.ts +++ b/packages/server/core/src/plugins/render/index.ts @@ -6,8 +6,6 @@ import { Middleware, ServerEnv, Render, - UserConfig, - CacheConfig, } from '../../types'; import { ServerNodeEnv } from '../../adapters/node/hono'; import { initReporter } from '../monitors'; @@ -17,27 +15,19 @@ import { CustomServer, getServerMidFromUnstableMid, } from '../customServer'; -import { createRender } from './render'; -export interface RenderPluginOptions { - staticGenerate?: boolean; - cacheConfig?: CacheConfig; -} +export * from './inject'; -export const renderPlugin = ( - options: RenderPluginOptions = {}, -): ServerPlugin => ({ +export const renderPlugin = (): ServerPlugin => ({ name: '@modern-js/plugin-render', setup(api) { - const { staticGenerate, cacheConfig } = options; - return { async prepare() { const { middlewares, routes, - metaName, + render, distDirectory: pwd, serverBase, } = api.useAppContext(); @@ -56,15 +46,6 @@ export const renderPlugin = ( const pageRoutes = getPageRoutes(routes); - const render = await getRenderHandler({ - pwd, - routes, - config, - metaName, - cacheConfig: config.render?.cache || cacheConfig, - staticGenerate, - }); - for (const route of pageRoutes) { const { urlPath: originUrlPath, entryName } = route; const urlPath = originUrlPath.endsWith('/') @@ -97,11 +78,12 @@ export const renderPlugin = ( handler: customServerMiddleware, }); - middlewares.push({ - name: `render`, - path: urlPath, - handler: createRenderHandler(render), - }); + render && + middlewares.push({ + name: `render`, + path: urlPath, + handler: createRenderHandler(render), + }); } }, }; @@ -155,37 +137,3 @@ function createRenderHandler( return c.body(body, status, headersData); }; } - -export interface GetRenderHandlerOptions { - pwd: string; - routes: ServerRoute[]; - config: UserConfig; - cacheConfig?: CacheConfig; - staticGenerate?: boolean; - metaName?: string; -} - -export async function getRenderHandler({ - pwd, - routes, - config, - cacheConfig, - metaName, - staticGenerate, -}: GetRenderHandlerOptions): Promise { - const ssrConfig = config.server?.ssr; - const forceCSR = typeof ssrConfig === 'object' ? ssrConfig.forceCSR : false; - - const render = createRender({ - routes, - pwd, - config, - staticGenerate, - cacheConfig, - forceCSR, - nonce: config.security?.nonce, - metaName: metaName || 'modern-js', - }); - - return render; -} diff --git a/packages/server/core/src/plugins/render/inject.ts b/packages/server/core/src/plugins/render/inject.ts new file mode 100644 index 000000000000..b5f10497d155 --- /dev/null +++ b/packages/server/core/src/plugins/render/inject.ts @@ -0,0 +1,74 @@ +import type { + CacheConfig, + GetRenderHandlerOptions, + Render, + ServerPlugin, +} from '../../types'; +import { createRender } from './render'; + +export interface InjectRenderHandlerOptions { + staticGenerate?: boolean; + cacheConfig?: CacheConfig; +} + +export const injectRenderHandlerPlugin = ({ + staticGenerate, + cacheConfig, +}: InjectRenderHandlerOptions): ServerPlugin => ({ + name: '@modern-js/plugin-inject-render', + setup(api) { + return { + async prepare() { + const { distDirectory: pwd, routes, metaName } = api.useAppContext(); + + const config = api.useConfigContext(); + + if (!routes) { + return; + } + + const getRenderHandlerOptions: GetRenderHandlerOptions = { + pwd, + routes, + config, + metaName, + cacheConfig: config.render?.cache || cacheConfig, + staticGenerate, + }; + + const render = await getRenderHandler(getRenderHandlerOptions); + + api.setAppContext({ + ...api.useAppContext(), + render, + getRenderOptions: getRenderHandlerOptions, + }); + }, + }; + }, +}); + +export async function getRenderHandler({ + pwd, + routes, + config, + cacheConfig, + metaName, + staticGenerate, +}: GetRenderHandlerOptions): Promise { + const ssrConfig = config.server?.ssr; + const forceCSR = typeof ssrConfig === 'object' ? ssrConfig.forceCSR : false; + + const render = createRender({ + routes, + pwd, + config, + staticGenerate, + cacheConfig, + forceCSR, + nonce: config.security?.nonce, + metaName: metaName || 'modern-js', + }); + + return render; +} diff --git a/packages/server/core/src/types/plugin.ts b/packages/server/core/src/types/plugin.ts index ba1dee37b792..5b914b7ad624 100644 --- a/packages/server/core/src/types/plugin.ts +++ b/packages/server/core/src/types/plugin.ts @@ -154,10 +154,22 @@ type Middleware = { order?: MiddlewareOrder; }; +export interface GetRenderHandlerOptions { + pwd: string; + routes: ServerRoute[]; + config: UserConfig; + cacheConfig?: CacheConfig; + staticGenerate?: boolean; + metaName?: string; +} + declare module '@modern-js/types' { export interface ISAppContext { middlewares: Middleware[]; metaName: string; + + getRenderOptions?: GetRenderHandlerOptions; + render?: Render; routes?: ServerRoute[]; nodeServer?: NodeServer; } diff --git a/packages/server/core/tests/plugins/render.test.ts b/packages/server/core/tests/plugins/render.test.ts index 10dba1e741c0..4218363b88e3 100644 --- a/packages/server/core/tests/plugins/render.test.ts +++ b/packages/server/core/tests/plugins/render.test.ts @@ -1,16 +1,26 @@ import path from 'path'; -import { ServerRoute } from '@modern-js/types'; -import { createLogger } from '@modern-js/utils'; +import { Logger, ServerRoute } from '@modern-js/types'; import { createServerBase } from '../../src/serverBase'; -import { - renderPlugin, - initMonitorsPlugin, - injectloggerPluigin, -} from '../../src/plugins'; +import { renderPlugin, createDefaultPlugins } from '../../src/plugins'; import { injectResourcePlugin } from '../../src/adapters/node/plugins'; import { getDefaultAppContext, getDefaultConfig } from '../helpers'; import { ServerUserConfig } from '../../src/types'; +const logger: Logger = { + error() { + // ignore + }, + info() { + // ignore + }, + warn() { + // ignore + }, + debug() { + // ignore + }, +}; + async function createSSRServer( pwd: string, serverConfig: ServerUserConfig = { ssr: true }, @@ -29,10 +39,11 @@ async function createSSRServer( }); server.addPlugins([ - initMonitorsPlugin(), - injectloggerPluigin(createLogger()), + ...createDefaultPlugins({ + logger, + }), injectResourcePlugin(), - renderPlugin({}), + renderPlugin(), ]); await server.init(); @@ -57,10 +68,11 @@ describe('should render html correctly', () => { }); server.addPlugins([ - initMonitorsPlugin(), - injectloggerPluigin(createLogger()), + ...createDefaultPlugins({ + logger, + }), injectResourcePlugin(), - renderPlugin({}), + renderPlugin(), ]); await server.init(); diff --git a/packages/server/prod-server/src/apply.ts b/packages/server/prod-server/src/apply.ts index 440692aa0193..7f6a70b33f42 100644 --- a/packages/server/prod-server/src/apply.ts +++ b/packages/server/prod-server/src/apply.ts @@ -2,15 +2,10 @@ import { ErrorDigest, ServerBase, createErrorHtml, - faviconPlugin, - logPlugin, - initMonitorsPlugin, - injectloggerPluigin, - injectServerTiming, onError, - processedByPlugin, renderPlugin, NodeServer, + createDefaultPlugins, } from '@modern-js/server-core'; import { serverStaticPlugin, @@ -55,19 +50,15 @@ export async function applyPlugins( const plugins = [ ...(nodeServer ? [injectNodeSeverPlugin({ nodeServer })] : []), - initMonitorsPlugin(), - injectloggerPluigin(getLogger()), - injectServerTiming(options.metaName), + ...createDefaultPlugins({ + cacheConfig, + staticGenerate: options.staticGenerate, + logger: getLogger(), + }), ...(options.plugins || []), - processedByPlugin(), - logPlugin(), injectResourcePlugin(), serverStaticPlugin(), - faviconPlugin(), - renderPlugin({ - staticGenerate: options.staticGenerate, - cacheConfig, - }), + renderPlugin(), ]; serverBase.addPlugins(plugins); diff --git a/packages/server/prod-server/src/types.ts b/packages/server/prod-server/src/types.ts index 69b048a23137..695a9391d4c7 100644 --- a/packages/server/prod-server/src/types.ts +++ b/packages/server/prod-server/src/types.ts @@ -1,6 +1,6 @@ import { ServerBaseOptions, - RenderPluginOptions, + CreateDefaultPluginsOptions, ServerPlugin, } from '@modern-js/server-core'; import { Reporter } from '@modern-js/types'; @@ -19,7 +19,7 @@ interface ProdServerExtraOptions { export type ProdServerOptions = Exclude & ProdServerExtraOptions & - RenderPluginOptions; + CreateDefaultPluginsOptions; export type BaseEnv = { Variables: {