diff --git a/packages/plugins/libs/qiankun/master/masterRuntimePlugin.tsx b/packages/plugins/libs/qiankun/master/masterRuntimePlugin.tsx index 13520cb78342..d8a70444f40d 100644 --- a/packages/plugins/libs/qiankun/master/masterRuntimePlugin.tsx +++ b/packages/plugins/libs/qiankun/master/masterRuntimePlugin.tsx @@ -77,6 +77,10 @@ function patchMicroAppRouteComponent(routes: any[]) { } export async function render(oldRender: typeof noop) { + // 在 ssr 的场景下,直接返回旧的 render + if (typeof window === 'undefined') { + return oldRender(); + } const runtimeOptions = await getMasterRuntime(); let masterOptions: MasterOptions = { ...getMasterOptions(), @@ -138,6 +142,10 @@ export async function render(oldRender: typeof noop) { } export function patchClientRoutes({ routes }: { routes: any[] }) { + // 在 ssr 的场景下,不执行主应用的 patchClientRoutes + if (typeof window === 'undefined') { + return; + } const microAppRoutes = [].concat( deepFilterLeafRoutes(routes), deepFilterLeafRoutes(microAppRuntimeRoutes), diff --git a/packages/plugins/libs/qiankun/slave/slaveRuntimePlugin.ts b/packages/plugins/libs/qiankun/slave/slaveRuntimePlugin.ts index e16244405db5..bd81f6bfc2e1 100644 --- a/packages/plugins/libs/qiankun/slave/slaveRuntimePlugin.ts +++ b/packages/plugins/libs/qiankun/slave/slaveRuntimePlugin.ts @@ -3,6 +3,10 @@ import { createHistory } from '@@/core/history'; import qiankunRender, { contextOptsStack } from './lifecycles'; export function render(oldRender: any) { + // 在 ssr 的场景下,直接返回旧的 render + if (typeof window === 'undefined') { + return oldRender(); + } return qiankunRender().then(oldRender); } diff --git a/packages/plugins/src/qiankun/master.ts b/packages/plugins/src/qiankun/master.ts index 29a332190db6..30ff0a914f43 100644 --- a/packages/plugins/src/qiankun/master.ts +++ b/packages/plugins/src/qiankun/master.ts @@ -210,4 +210,18 @@ export { MicroAppWithMemoHistory } from './MicroAppWithMemoHistory'; `, }); }); + + api.chainWebpack((config, { ssr }) => { + // 在 ssr 的场景下,把 qiankun external 到一个任意模块 + // 这样就不会把 qiankun 的依赖构建进产物中 + if (ssr) { + const originalExternals = config.get('externals'); + config.externals({ + ...originalExternals, + qiankun: 'fs', + }); + } + + return config; + }); }; diff --git a/packages/plugins/src/qiankun/slave.ts b/packages/plugins/src/qiankun/slave.ts index 2e976c28149b..f862601a14d3 100644 --- a/packages/plugins/src/qiankun/slave.ts +++ b/packages/plugins/src/qiankun/slave.ts @@ -180,7 +180,11 @@ export interface IRuntimeConfig { ]; }); - api.chainWebpack((config) => { + api.chainWebpack((config, { ssr }) => { + // ssr 场景下,通过 cjs 的方式来使用模块,跳过 umd方式的构建 + if (ssr) { + return; + } assert(api.pkg.name, 'You should have name in package.json.'); // 默认不修改 library chunk 的 name,从而确保可以通过 window[appName] 访问到导出 // mfsu 关闭的时候才可以修改,否则可能导致配合 mfsu 时,子应用的 umd chunk 无法被正确加载 @@ -223,11 +227,14 @@ export interface IRuntimeConfig { api.addEntryCode(() => [ ` -export const bootstrap = qiankun_genBootstrap(render); -export const mount = qiankun_genMount('${api.config.mountElementId}'); -export const unmount = qiankun_genUnmount('${api.config.mountElementId}'); -export const update = qiankun_genUpdate(); -if (!window.__POWERED_BY_QIANKUN__) { +const qiankun_noop = () => new Error('qiankun lifecycle is not available for server runtime!'); +const ssrBuildTarget = process.env.SSR_BUILD_TARGET; +export const bootstrap = ssrBuildTarget ? qiankun_noop: qiankun_genBootstrap(render); +export const mount = ssrBuildTarget ? qiankun_noop : qiankun_genMount('${api.config.mountElementId}'); +export const unmount = ssrBuildTarget ? qiankun_noop : qiankun_genUnmount('${api.config.mountElementId}'); +export const update = ssrBuildTarget ? qiankun_noop : qiankun_genUpdate(); +// 增加 ssr 的判断 +if (typeof window !== 'undefined' && !window.__POWERED_BY_QIANKUN__) { bootstrap().then(mount); } `, diff --git a/packages/preset-umi/src/types.ts b/packages/preset-umi/src/types.ts index cbbadade3f38..913866833417 100644 --- a/packages/preset-umi/src/types.ts +++ b/packages/preset-umi/src/types.ts @@ -129,6 +129,7 @@ export type IApi = PluginAPI & memo: WebpackChain, args: { env: Env; + ssr?: boolean; webpack: typeof webpack; }, ): void;