forgeplus-react/server/render.js

100 lines
3.0 KiB
JavaScript
Raw Normal View History

2023-12-26 13:49:10 +08:00
import React from "react";
import {renderToString} from "react-dom/server";
2024-01-05 15:01:16 +08:00
import {StaticRouter, matchPath} from "react-router-dom";
2024-01-31 11:14:52 +08:00
import {renderRoutes} from "react-router-config";
2024-01-05 15:01:16 +08:00
import Routes, { deepRoutes } from "../Routes";
2023-12-26 13:49:10 +08:00
import { Provider } from "react-redux";
2024-01-05 15:01:16 +08:00
import { serverStore } from "../src/redux/stores/configureStore";
import App from "../src/App";
import { Route } from 'react-router-dom';
2024-01-12 10:11:16 +08:00
import { setDefaultMeta } from '../src/common/UrlTool'
2024-01-15 09:51:04 +08:00
import Logger from "./log";
2024-01-05 15:01:16 +08:00
export const render = async (req,res)=>{
let _route = null,
_match = null;
2024-01-15 09:51:04 +08:00
Logger.info(`${req.url} UA:${req.headers['user-agent']}`)
2024-01-05 15:01:16 +08:00
2024-01-12 10:11:16 +08:00
let store = serverStore();
2023-12-26 13:49:10 +08:00
2024-01-05 15:01:16 +08:00
function matchSubRoutes(routes, url) {
for (const route of routes) {
// 检查当前路由是否匹配
let match = matchPath(url, route.path);
if (match) {
// 如果当前路由匹配,并且它有子路由,递归检查子路由
if (route.routes) {
// 递归调用匹配子路由
const subMatch = matchSubRoutes(route.routes, url);
if (subMatch) {
_route = route;
_match = subMatch;
return true;
}
}
// 如果没有子路由,或者子路由不匹配,但当前路由匹配,返回当前路由
_route = route;
_match = match;
return true;
}
}
// 如果没有找到匹配的路由返回false
return false;
}
matchSubRoutes(deepRoutes, req.url.split("?")[0])
let context = {
code: 200,
2023-12-26 13:49:10 +08:00
};
2024-01-05 15:01:16 +08:00
if (_route && _route.component && _route.component.preFetch) {
context = await _route.component.preFetch({
store,
match: _match,
query: req.path,
});
}
2023-12-26 13:49:10 +08:00
const content = renderToString((
2024-01-05 15:01:16 +08:00
<Provider store={store}>
<StaticRouter location={req.path} context={context}>
2024-01-31 11:14:52 +08:00
{renderRoutes(Routes)}
{/* <Route path='/:owner/:projectsId' exact component={App}></Route> */}
2024-01-05 15:01:16 +08:00
</StaticRouter>
2023-12-26 13:49:10 +08:00
</Provider>
2023-12-29 16:43:14 +08:00
))
2023-12-26 13:49:10 +08:00
2024-01-12 10:11:16 +08:00
if (!content) {
// 未匹配到详情页恢复默认header
setDefaultMeta()
} else {
// 匹配到服务端渲染页面注入state
let script = domObj.window.document.getElementById('initState')
if (!script) {
script = domObj.window.document.createElement('script')
script.setAttribute('id', 'initState')
}
script.textContent = `window.__initState__ = ${ JSON.stringify(store.getState()) }`
2024-07-15 09:04:07 +08:00
const styleNode = domObj.window.document.createElement('style')
styleNode.type = 'text/css'
// styleNode.innerHTML = `${ [...css].join('') }`
styleNode.innerHTML = detailCss
2024-01-12 10:11:16 +08:00
domObj.window.document.head.appendChild(script);
2024-07-15 09:04:07 +08:00
domObj.window.document.head.appendChild(styleNode);
2024-01-05 15:01:16 +08:00
}
2024-01-12 10:11:16 +08:00
let html = domObj.serialize()
2023-12-26 13:49:10 +08:00
const prepHTML=(data,rootString)=>{
data=data.replace('<div id="root" class="page -layout-v -fit widthunit"></div>',`<div id="root" class="page -layout-v -fit widthunit">${rootString}</div>`);
return data;
}
res.send(prepHTML(html, content))
2024-01-12 10:11:16 +08:00
store = null
2023-12-26 13:49:10 +08:00
}