From 8c8a8d17ee05ba9dd922475568bb3f4937404d1d Mon Sep 17 00:00:00 2001 From: "jay.kou" Date: Sun, 25 Feb 2024 15:08:53 +0800 Subject: [PATCH 1/7] fix: ssr exportStatic not handle with base --- examples/ssr-export-static-basename/.umirc.ts | 6 ++++++ examples/ssr-export-static-basename/package.json | 14 ++++++++++++++ .../src/pages/about/index.tsx | 15 +++++++++++++++ .../src/pages/index.tsx | 15 +++++++++++++++ .../preset-umi/src/features/tmpFiles/tmpFiles.ts | 1 + packages/preset-umi/templates/server.tpl | 2 +- packages/server/src/ssr.ts | 3 +++ 7 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 examples/ssr-export-static-basename/.umirc.ts create mode 100644 examples/ssr-export-static-basename/package.json create mode 100644 examples/ssr-export-static-basename/src/pages/about/index.tsx create mode 100644 examples/ssr-export-static-basename/src/pages/index.tsx diff --git a/examples/ssr-export-static-basename/.umirc.ts b/examples/ssr-export-static-basename/.umirc.ts new file mode 100644 index 000000000000..698110bb984d --- /dev/null +++ b/examples/ssr-export-static-basename/.umirc.ts @@ -0,0 +1,6 @@ +export default { + ssr: {}, + exportStatic: {}, + hash: true, + base: '/a/', +}; diff --git a/examples/ssr-export-static-basename/package.json b/examples/ssr-export-static-basename/package.json new file mode 100644 index 000000000000..b4a4abb94994 --- /dev/null +++ b/examples/ssr-export-static-basename/package.json @@ -0,0 +1,14 @@ +{ + "name": "@example/ssr-export-static-basename", + "private": true, + "description": "当 umi 配置表中设置了 base 后, ssr 输出的预渲染页面中的 a 标签需要有正确的 base 前缀", + "scripts": { + "build": "umi build", + "dev": "umi dev", + "setup": "umi setup", + "start": "npm run dev" + }, + "dependencies": { + "umi": "workspace:*" + } +} diff --git a/examples/ssr-export-static-basename/src/pages/about/index.tsx b/examples/ssr-export-static-basename/src/pages/about/index.tsx new file mode 100644 index 000000000000..28f2271f776b --- /dev/null +++ b/examples/ssr-export-static-basename/src/pages/about/index.tsx @@ -0,0 +1,15 @@ +import { Link } from 'umi'; + +const About = () => { + return ( +
+
+ about page +
+
+ to home +
+ ); +}; + +export default About; diff --git a/examples/ssr-export-static-basename/src/pages/index.tsx b/examples/ssr-export-static-basename/src/pages/index.tsx new file mode 100644 index 000000000000..683660fae3ba --- /dev/null +++ b/examples/ssr-export-static-basename/src/pages/index.tsx @@ -0,0 +1,15 @@ +import { Link } from 'umi'; + +const Home = () => { + return ( +
+
+ home page +
+
+ to about +
+ ); +}; + +export default Home; diff --git a/packages/preset-umi/src/features/tmpFiles/tmpFiles.ts b/packages/preset-umi/src/features/tmpFiles/tmpFiles.ts index 305727e5458c..f75e00c4e4bc 100644 --- a/packages/preset-umi/src/features/tmpFiles/tmpFiles.ts +++ b/packages/preset-umi/src/features/tmpFiles/tmpFiles.ts @@ -562,6 +562,7 @@ if (process.env.NODE_ENV === 'development') { __INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, ), mountElementId, + basename: api.config.base, }, }); } diff --git a/packages/preset-umi/templates/server.tpl b/packages/preset-umi/templates/server.tpl index e33d49b21168..c0876b6e90d7 100644 --- a/packages/preset-umi/templates/server.tpl +++ b/packages/preset-umi/templates/server.tpl @@ -62,7 +62,7 @@ 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}}}' }; const requestHandler = createRequestHandler(createOpts); /** diff --git a/packages/server/src/ssr.ts b/packages/server/src/ssr.ts index d428a8640f81..8dd62639a38a 100644 --- a/packages/server/src/ssr.ts +++ b/packages/server/src/ssr.ts @@ -54,6 +54,7 @@ interface CreateRequestHandlerOptions extends CreateRequestServerlessOptions { pureHtml: boolean; }; mountElementId: string; + basename?: string; } interface IExecLoaderOpts { @@ -93,6 +94,7 @@ function createJSXGenerator(opts: CreateRequestHandlerOptions) { getRoutes, createHistory, sourceDir, + basename, } = opts; // make import { history } from 'umi' work @@ -169,6 +171,7 @@ function createJSXGenerator(opts: CreateRequestHandlerOptions) { __INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: opts.__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, mountElementId: opts.mountElementId, + basename, }; const element = (await opts.getClientRootComponent( context, From 13d41a5c0039ef56deabc97abae037006c90c232 Mon Sep 17 00:00:00 2001 From: "jay.kou" Date: Mon, 26 Feb 2024 10:19:00 +0800 Subject: [PATCH 2/7] fix: update pnpm-lock.yaml --- pnpm-lock.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 16b832815088..a270c271331a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1151,6 +1151,12 @@ importers: specifier: workspace:* version: link:../../packages/umi + examples/ssr-export-static-basename: + dependencies: + umi: + specifier: workspace:* + version: link:../../packages/umi + examples/ssr-todos: dependencies: axios: @@ -24139,6 +24145,7 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 + dev: false /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} From 9ba2542668ac3686c99c02a396cfb7fa138a04af Mon Sep 17 00:00:00 2001 From: "jay.kou" Date: Thu, 11 Jul 2024 18:36:11 +0800 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20getClientRootCo?= =?UTF-8?q?mponent=20=E6=96=B9=E6=B3=95.=20=E5=A2=9E=E5=8A=A0=20ssr=20base?= =?UTF-8?q?name=20=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/ssg-basename/.umirc.ts | 6 +++ examples/ssg-basename/package.json | 14 +++++++ examples/ssg-basename/src/layouts/index.tsx | 14 +++++++ .../ssg-basename/src/pages/about/index.tsx | 24 ++++++++++++ examples/ssg-basename/src/pages/index.tsx | 24 ++++++++++++ .../.umirc.ts | 3 +- .../package.json | 0 examples/ssr-basename/plugins/mylogger.ts | 37 +++++++++++++++++++ examples/ssr-basename/plugins/picker.ts | 28 ++++++++++++++ examples/ssr-basename/src/layouts/index.tsx | 14 +++++++ .../src/pages/about/form/index.tsx | 3 ++ .../ssr-basename/src/pages/about/index.tsx | 24 ++++++++++++ examples/ssr-basename/src/pages/index.tsx | 24 ++++++++++++ .../src/pages/about/index.tsx | 15 -------- .../src/pages/index.tsx | 15 -------- .../src/features/exportStatic/exportStatic.ts | 23 +++++++++++- packages/renderer-react/src/server.tsx | 5 +++ packages/server/src/ssr.ts | 17 +++++++-- pnpm-lock.yaml | 19 ++++++---- 19 files changed, 265 insertions(+), 44 deletions(-) create mode 100644 examples/ssg-basename/.umirc.ts create mode 100644 examples/ssg-basename/package.json create mode 100644 examples/ssg-basename/src/layouts/index.tsx create mode 100644 examples/ssg-basename/src/pages/about/index.tsx create mode 100644 examples/ssg-basename/src/pages/index.tsx rename examples/{ssr-export-static-basename => ssr-basename}/.umirc.ts (63%) rename examples/{ssr-export-static-basename => ssr-basename}/package.json (100%) create mode 100644 examples/ssr-basename/plugins/mylogger.ts create mode 100644 examples/ssr-basename/plugins/picker.ts create mode 100644 examples/ssr-basename/src/layouts/index.tsx create mode 100644 examples/ssr-basename/src/pages/about/form/index.tsx create mode 100644 examples/ssr-basename/src/pages/about/index.tsx create mode 100644 examples/ssr-basename/src/pages/index.tsx delete mode 100644 examples/ssr-export-static-basename/src/pages/about/index.tsx delete mode 100644 examples/ssr-export-static-basename/src/pages/index.tsx diff --git a/examples/ssg-basename/.umirc.ts b/examples/ssg-basename/.umirc.ts new file mode 100644 index 000000000000..46e48430dff0 --- /dev/null +++ b/examples/ssg-basename/.umirc.ts @@ -0,0 +1,6 @@ +export default { + exportStatic: {}, + ssr: {}, + base: '/base/', + publicPath: '/base/', // 布署时需要布署在 base 文件夹下. +}; diff --git a/examples/ssg-basename/package.json b/examples/ssg-basename/package.json new file mode 100644 index 000000000000..516ef6602368 --- /dev/null +++ b/examples/ssg-basename/package.json @@ -0,0 +1,14 @@ +{ + "name": "@example/ssg-basename", + "private": true, + "description": "该案例用于测试 ssg 预渲染. 当 umi 配置表中设置了 base 后, ssg 输出的预渲染页面中的 a 标签需要有正确的 base 前缀", + "scripts": { + "build": "umi build", + "dev": "umi dev", + "setup": "umi setup", + "start": "npm run dev" + }, + "dependencies": { + "umi": "workspace:*" + } +} diff --git a/examples/ssg-basename/src/layouts/index.tsx b/examples/ssg-basename/src/layouts/index.tsx new file mode 100644 index 000000000000..6ec507a5a7fa --- /dev/null +++ b/examples/ssg-basename/src/layouts/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import { Outlet } from 'umi'; + +const Layout = () => { + return ( +
+
HEADER
+ +
+ ); +}; + +export default Layout; diff --git a/examples/ssg-basename/src/pages/about/index.tsx b/examples/ssg-basename/src/pages/about/index.tsx new file mode 100644 index 000000000000..e5d53662f556 --- /dev/null +++ b/examples/ssg-basename/src/pages/about/index.tsx @@ -0,0 +1,24 @@ +import React, { useState } from 'react'; +import { Link } from 'umi'; + +const About = () => { + const [num, setNum] = useState(0); + + return ( +
+
+ ABOUT page + +
+
+ to home +
+ ); +}; + +export default About; diff --git a/examples/ssg-basename/src/pages/index.tsx b/examples/ssg-basename/src/pages/index.tsx new file mode 100644 index 000000000000..9385801fa5d1 --- /dev/null +++ b/examples/ssg-basename/src/pages/index.tsx @@ -0,0 +1,24 @@ +import React, { useState } from 'react'; +import { Link } from 'umi'; + +const Home = () => { + const [num, setNum] = useState(0); + return ( +
+
+ HOME page + +
+ +
+ to about +
+ ); +}; + +export default Home; diff --git a/examples/ssr-export-static-basename/.umirc.ts b/examples/ssr-basename/.umirc.ts similarity index 63% rename from examples/ssr-export-static-basename/.umirc.ts rename to examples/ssr-basename/.umirc.ts index 698110bb984d..6b596c65a98c 100644 --- a/examples/ssr-export-static-basename/.umirc.ts +++ b/examples/ssr-basename/.umirc.ts @@ -1,6 +1,5 @@ export default { ssr: {}, exportStatic: {}, - hash: true, - base: '/a/', + base: '/base/', }; diff --git a/examples/ssr-export-static-basename/package.json b/examples/ssr-basename/package.json similarity index 100% rename from examples/ssr-export-static-basename/package.json rename to examples/ssr-basename/package.json diff --git a/examples/ssr-basename/plugins/mylogger.ts b/examples/ssr-basename/plugins/mylogger.ts new file mode 100644 index 000000000000..8a7f85731fdd --- /dev/null +++ b/examples/ssr-basename/plugins/mylogger.ts @@ -0,0 +1,37 @@ +import { writeFileSync } from 'fs'; +import { IApi } from 'umi'; + +export default (api: IApi) => { + api.describe({ + key: 'mylogger', + config: { + schema(joi) { + return joi.string(); + }, + }, + enableBy: api.EnableBy.register, + }); + + api.registerMethod({ + name: 'mylogger', + fn: (pathname, obj) => { + let cache = []; + const str = JSON.stringify(obj, function (key, value) { + if (typeof value === 'object' && value !== null) { + if (cache.indexOf(value) !== -1) { + // 移除 + return; + } + // 收集所有的值 + cache.push(value); + } + return value; + }); + cache = null; + + writeFileSync(pathname, str, () => { + console.log('write log finish'); + }); + }, + }); +}; diff --git a/examples/ssr-basename/plugins/picker.ts b/examples/ssr-basename/plugins/picker.ts new file mode 100644 index 000000000000..8b87eddef6c2 --- /dev/null +++ b/examples/ssr-basename/plugins/picker.ts @@ -0,0 +1,28 @@ +import type { IApi } from 'umi'; + +export default (api: IApi) => { + api.describe({ + key: 'routePicker', + config: { + schema({ zod }) { + return zod.array(zod.string()); + }, + }, + enableBy: () => { + return api.name === 'dev'; + }, + }); + + console.log('插件 picker 注册'); + + api.onCheck(async () => { + // console.log('插件', api.appData.routes); + console.log('插件config', api.config); + api.config.routes = [ + { + path: '/', + component: 'index', + }, + ]; + }); +}; diff --git a/examples/ssr-basename/src/layouts/index.tsx b/examples/ssr-basename/src/layouts/index.tsx new file mode 100644 index 000000000000..6ec507a5a7fa --- /dev/null +++ b/examples/ssr-basename/src/layouts/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import { Outlet } from 'umi'; + +const Layout = () => { + return ( +
+
HEADER
+ +
+ ); +}; + +export default Layout; diff --git a/examples/ssr-basename/src/pages/about/form/index.tsx b/examples/ssr-basename/src/pages/about/form/index.tsx new file mode 100644 index 000000000000..f94fd6d91678 --- /dev/null +++ b/examples/ssr-basename/src/pages/about/form/index.tsx @@ -0,0 +1,3 @@ +export default function AboutForm() { + return
About Form
; +} diff --git a/examples/ssr-basename/src/pages/about/index.tsx b/examples/ssr-basename/src/pages/about/index.tsx new file mode 100644 index 000000000000..e5d53662f556 --- /dev/null +++ b/examples/ssr-basename/src/pages/about/index.tsx @@ -0,0 +1,24 @@ +import React, { useState } from 'react'; +import { Link } from 'umi'; + +const About = () => { + const [num, setNum] = useState(0); + + return ( +
+
+ ABOUT page + +
+
+ to home +
+ ); +}; + +export default About; diff --git a/examples/ssr-basename/src/pages/index.tsx b/examples/ssr-basename/src/pages/index.tsx new file mode 100644 index 000000000000..9385801fa5d1 --- /dev/null +++ b/examples/ssr-basename/src/pages/index.tsx @@ -0,0 +1,24 @@ +import React, { useState } from 'react'; +import { Link } from 'umi'; + +const Home = () => { + const [num, setNum] = useState(0); + return ( +
+
+ HOME page + +
+ +
+ to about +
+ ); +}; + +export default Home; diff --git a/examples/ssr-export-static-basename/src/pages/about/index.tsx b/examples/ssr-export-static-basename/src/pages/about/index.tsx deleted file mode 100644 index 28f2271f776b..000000000000 --- a/examples/ssr-export-static-basename/src/pages/about/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Link } from 'umi'; - -const About = () => { - return ( -
-
- about page -
-
- to home -
- ); -}; - -export default About; diff --git a/examples/ssr-export-static-basename/src/pages/index.tsx b/examples/ssr-export-static-basename/src/pages/index.tsx deleted file mode 100644 index 683660fae3ba..000000000000 --- a/examples/ssr-export-static-basename/src/pages/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Link } from 'umi'; - -const Home = () => { - return ( -
-
- home page -
-
- to about -
- ); -}; - -export default Home; diff --git a/packages/preset-umi/src/features/exportStatic/exportStatic.ts b/packages/preset-umi/src/features/exportStatic/exportStatic.ts index ae0d2f9be2b2..da12a00e7e63 100644 --- a/packages/preset-umi/src/features/exportStatic/exportStatic.ts +++ b/packages/preset-umi/src/features/exportStatic/exportStatic.ts @@ -60,13 +60,32 @@ function getExportHtmlData(routes: Record): IExportHtmlItem[] { async function getPreRenderedHTML(api: IApi, htmlTpl: string, path: string) { const { exportStatic: { ignorePreRenderError = false }, + base, } = api.config; markupRender ??= require(absServerBuildPath(api))._markupGenerator; try { - const html = await markupRender(path); + const location = `${base.endsWith('/') ? base.slice(0, -1) : base}${path}`; + const markup = await markupRender(location); + const [mainTpl, extraTpl = ''] = markup.split(''); + // TODO: improve return type for markup generator + const helmetContent = mainTpl.match( + /[^]*?(<[^>]+data-rh[^]+)<\/head>/, + )?.[1]; + const bodyContent = mainTpl.match(/]*>([^]+?)<\/body>/)?.[1]; + + htmlTpl = htmlTpl + // append helmet content + .replace('', `${helmetContent || ''}`) + // replace #root with pre-rendered body content + .replace( + new RegExp(`
]*>.*?
`), + bodyContent, + ) + // append hidden templates + .replace(/$/, `${extraTpl}`); logger.info(`Pre-render for ${path}`); - return html; + return htmlTpl; } catch (err) { logger.error(`Pre-render ${path} error: ${err}`); if (!ignorePreRenderError) { diff --git a/packages/renderer-react/src/server.tsx b/packages/renderer-react/src/server.tsx index 39fb97b290d1..fb3cb2b07adf 100644 --- a/packages/renderer-react/src/server.tsx +++ b/packages/renderer-react/src/server.tsx @@ -23,7 +23,12 @@ export async function getClientRootComponent(opts: IRootComponentOptions) { routes: clientRoutes, }, }); + let rootContainer = ( + // 这里的 location 需要包含 basename, 否则会影响 StaticRouter 的匹配. + // 由于 getClientRootComponent 方法会同时用于 ssr 和 ssg, 所以在调用该方法时需要注意传入的 location 是否包含 basename. + // 1. 在用于 ssr 时传入的 location 来源于 request.url, 它是包含 basename 的, 所以没有问题. + // 2. 但是在用于 ssg 时(static export), 需要注意传入的 locaiton 要拼接上 basename. diff --git a/packages/server/src/ssr.ts b/packages/server/src/ssr.ts index 8dd62639a38a..75c9c8fdd5be 100644 --- a/packages/server/src/ssr.ts +++ b/packages/server/src/ssr.ts @@ -112,7 +112,8 @@ function createJSXGenerator(opts: CreateRequestHandlerOptions) { }, }); - const matches = matchRoutesForSSR(url, routes); + const matches = matchRoutesForSSR(url, routes, basename); + if (matches.length === 0) { return; } @@ -606,9 +607,19 @@ export function createAppRootElement(opts: CreateRequestHandlerOptions) { }; } -function matchRoutesForSSR(reqUrl: string, routesById: IRoutesById) { +function matchRoutesForSSR( + reqUrl: string, + routesById: IRoutesById, + basename?: string, +) { + // react-router-dom 在 v6.4.0 版本上增加了对 basename 结尾为斜杠的支持 + // 目前 @umijs/server 依赖的 react-router-dom 版本为 v6.3.0 + // 如果传入的 basename 结尾带斜杠, 比如 '/base/', 则会匹配不到. + // 日后如果依赖的版本升级, 此段代码可以删除. + const _basename = basename?.endsWith('/') ? basename.slice(0, -1) : basename; + return ( - matchRoutes(createClientRoutes({ routesById }), reqUrl)?.map( + matchRoutes(createClientRoutes({ routesById }), reqUrl, _basename)?.map( (route: any) => route.route.id, ) || [] ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a270c271331a..8f2207d4ee19 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1127,6 +1127,18 @@ importers: specifier: workspace:* version: link:../../packages/umi + examples/ssg-basename: + dependencies: + umi: + specifier: workspace:* + version: link:../../packages/umi + + examples/ssr-basename: + dependencies: + umi: + specifier: workspace:* + version: link:../../packages/umi + examples/ssr-demo: dependencies: '@ant-design/cssinjs': @@ -1151,12 +1163,6 @@ importers: specifier: workspace:* version: link:../../packages/umi - examples/ssr-export-static-basename: - dependencies: - umi: - specifier: workspace:* - version: link:../../packages/umi - examples/ssr-todos: dependencies: axios: @@ -24145,7 +24151,6 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - dev: false /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} From e3cf1cf246fd54be3947adecda42c3b90f8b5687 Mon Sep 17 00:00:00 2001 From: "jay.kou" Date: Thu, 11 Jul 2024 19:00:52 +0800 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20exportStatic=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/features/exportStatic/exportStatic.ts | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/packages/preset-umi/src/features/exportStatic/exportStatic.ts b/packages/preset-umi/src/features/exportStatic/exportStatic.ts index da12a00e7e63..f9044e573694 100644 --- a/packages/preset-umi/src/features/exportStatic/exportStatic.ts +++ b/packages/preset-umi/src/features/exportStatic/exportStatic.ts @@ -66,26 +66,9 @@ async function getPreRenderedHTML(api: IApi, htmlTpl: string, path: string) { try { const location = `${base.endsWith('/') ? base.slice(0, -1) : base}${path}`; - const markup = await markupRender(location); - const [mainTpl, extraTpl = ''] = markup.split(''); - // TODO: improve return type for markup generator - const helmetContent = mainTpl.match( - /[^]*?(<[^>]+data-rh[^]+)<\/head>/, - )?.[1]; - const bodyContent = mainTpl.match(/]*>([^]+?)<\/body>/)?.[1]; - - htmlTpl = htmlTpl - // append helmet content - .replace('', `${helmetContent || ''}`) - // replace #root with pre-rendered body content - .replace( - new RegExp(`
]*>.*?
`), - bodyContent, - ) - // append hidden templates - .replace(/$/, `${extraTpl}`); + const html = await markupRender(location); logger.info(`Pre-render for ${path}`); - return htmlTpl; + return html; } catch (err) { logger.error(`Pre-render ${path} error: ${err}`); if (!ignorePreRenderError) { From d433ed0b36ac9e5a2a663d7b2d0f46693be8065a Mon Sep 17 00:00:00 2001 From: "jay.kou" Date: Thu, 1 Aug 2024 17:12:22 +0800 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=86=B2=E7=AA=81=E5=AF=BC=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/preset-umi/templates/server.tpl | 2 +- packages/renderer-react/src/server.tsx | 2 +- packages/renderer-react/src/types.ts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/preset-umi/templates/server.tpl b/packages/preset-umi/templates/server.tpl index c0876b6e90d7..1c17334cb48a 100644 --- a/packages/preset-umi/templates/server.tpl +++ b/packages/preset-umi/templates/server.tpl @@ -61,7 +61,7 @@ const createOpts = { ServerInsertedHTMLContext, htmlPageOpts: {{{htmlPageOpts}}}, __INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {{{__INTERNAL_DO_NOT_USE_OR_YOU_WILL_BE_FIRED}}}, - mountElementId: '{{{mountElementId}}}' + mountElementId: '{{{mountElementId}}}', basename: '{{{basename}}}' }; const requestHandler = createRequestHandler(createOpts); diff --git a/packages/renderer-react/src/server.tsx b/packages/renderer-react/src/server.tsx index fb3cb2b07adf..e10690e9f962 100644 --- a/packages/renderer-react/src/server.tsx +++ b/packages/renderer-react/src/server.tsx @@ -8,7 +8,7 @@ import { IRootComponentOptions } from './types'; // Get the root React component for ReactDOMServer.renderToString export async function getClientRootComponent(opts: IRootComponentOptions) { - const basename = '/'; + const basename = opts.basename || '/'; const components = { ...opts.routeComponents }; // todo 参数对齐 const clientRoutes = createClientRoutes({ diff --git a/packages/renderer-react/src/types.ts b/packages/renderer-react/src/types.ts index ea92648b89bf..c7c05b6a59f9 100644 --- a/packages/renderer-react/src/types.ts +++ b/packages/renderer-react/src/types.ts @@ -77,6 +77,7 @@ export interface IRootComponentOptions extends IHtmlHydrateOptions { location: string; loaderData: { [routeKey: string]: any }; manifest: any; + basename?: string; } export interface IHtmlProps extends IHtmlHydrateOptions { From 46f61c6f16abf0572f04bd2aafaf49675ce3b11b Mon Sep 17 00:00:00 2001 From: "jay.kou" Date: Thu, 1 Aug 2024 17:15:07 +0800 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E4=BE=8B=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/ssr-basename/package.json | 4 ++-- examples/ssr-basename/src/pages/about/form/index.tsx | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 examples/ssr-basename/src/pages/about/form/index.tsx diff --git a/examples/ssr-basename/package.json b/examples/ssr-basename/package.json index b4a4abb94994..7b471696e43a 100644 --- a/examples/ssr-basename/package.json +++ b/examples/ssr-basename/package.json @@ -1,7 +1,7 @@ { - "name": "@example/ssr-export-static-basename", + "name": "@example/ssr-basename", "private": true, - "description": "当 umi 配置表中设置了 base 后, ssr 输出的预渲染页面中的 a 标签需要有正确的 base 前缀", + "description": "该案例用于测试 SSR 中带 basename 的情况. 在 dev 或 build 下, 服务端需要返回正确的 html 片段, 比如 a 标签需要有正确的 base 前缀", "scripts": { "build": "umi build", "dev": "umi dev", diff --git a/examples/ssr-basename/src/pages/about/form/index.tsx b/examples/ssr-basename/src/pages/about/form/index.tsx deleted file mode 100644 index f94fd6d91678..000000000000 --- a/examples/ssr-basename/src/pages/about/form/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function AboutForm() { - return
About Form
; -} From ec74ef81bff9218bc8001820358f460e3e30a96b Mon Sep 17 00:00:00 2001 From: "jay.kou" Date: Thu, 1 Aug 2024 17:15:07 +0800 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E4=BE=8B=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/ssr-basename/package.json | 4 +- examples/ssr-basename/plugins/mylogger.ts | 37 ------------------- examples/ssr-basename/plugins/picker.ts | 28 -------------- .../src/pages/about/form/index.tsx | 3 -- 4 files changed, 2 insertions(+), 70 deletions(-) delete mode 100644 examples/ssr-basename/plugins/mylogger.ts delete mode 100644 examples/ssr-basename/plugins/picker.ts delete mode 100644 examples/ssr-basename/src/pages/about/form/index.tsx diff --git a/examples/ssr-basename/package.json b/examples/ssr-basename/package.json index b4a4abb94994..7b471696e43a 100644 --- a/examples/ssr-basename/package.json +++ b/examples/ssr-basename/package.json @@ -1,7 +1,7 @@ { - "name": "@example/ssr-export-static-basename", + "name": "@example/ssr-basename", "private": true, - "description": "当 umi 配置表中设置了 base 后, ssr 输出的预渲染页面中的 a 标签需要有正确的 base 前缀", + "description": "该案例用于测试 SSR 中带 basename 的情况. 在 dev 或 build 下, 服务端需要返回正确的 html 片段, 比如 a 标签需要有正确的 base 前缀", "scripts": { "build": "umi build", "dev": "umi dev", diff --git a/examples/ssr-basename/plugins/mylogger.ts b/examples/ssr-basename/plugins/mylogger.ts deleted file mode 100644 index 8a7f85731fdd..000000000000 --- a/examples/ssr-basename/plugins/mylogger.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { writeFileSync } from 'fs'; -import { IApi } from 'umi'; - -export default (api: IApi) => { - api.describe({ - key: 'mylogger', - config: { - schema(joi) { - return joi.string(); - }, - }, - enableBy: api.EnableBy.register, - }); - - api.registerMethod({ - name: 'mylogger', - fn: (pathname, obj) => { - let cache = []; - const str = JSON.stringify(obj, function (key, value) { - if (typeof value === 'object' && value !== null) { - if (cache.indexOf(value) !== -1) { - // 移除 - return; - } - // 收集所有的值 - cache.push(value); - } - return value; - }); - cache = null; - - writeFileSync(pathname, str, () => { - console.log('write log finish'); - }); - }, - }); -}; diff --git a/examples/ssr-basename/plugins/picker.ts b/examples/ssr-basename/plugins/picker.ts deleted file mode 100644 index 8b87eddef6c2..000000000000 --- a/examples/ssr-basename/plugins/picker.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { IApi } from 'umi'; - -export default (api: IApi) => { - api.describe({ - key: 'routePicker', - config: { - schema({ zod }) { - return zod.array(zod.string()); - }, - }, - enableBy: () => { - return api.name === 'dev'; - }, - }); - - console.log('插件 picker 注册'); - - api.onCheck(async () => { - // console.log('插件', api.appData.routes); - console.log('插件config', api.config); - api.config.routes = [ - { - path: '/', - component: 'index', - }, - ]; - }); -}; diff --git a/examples/ssr-basename/src/pages/about/form/index.tsx b/examples/ssr-basename/src/pages/about/form/index.tsx deleted file mode 100644 index f94fd6d91678..000000000000 --- a/examples/ssr-basename/src/pages/about/form/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function AboutForm() { - return
About Form
; -}