Open gnosis23 opened 2 years ago
直接用 webpack 打包 node 代码
// webpack.config.js
const path = require("path")
const webpackNodeExternals = require("webpack-node-externals")
module.exports = {
target: "node",
mode: "development",
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "build"),
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/,
},
],
},
externals: [
// 不要把 node_modules 里的代码打包进去
webpackNodeExternals()
]
}
server端的代码如下:
import express from "express"
import React from "react"
import { renderToString } from "react-dom/server"
import Home from "./client/components/Home"
const app = express()
app.use(express.static("public"))
app.get("/", (req, res) => {
const content = renderToString(<Home />)
const html = `
<html>
<head></head>
<body>
<div id="root">${content}</div>
<script src="bundle.js"></script>
</body>
</html>
`
res.send(html)
})
app.listen(3000, () => {
console.log('listening on port 3000')
})
比如 React-Router 和 Redux 都号称支持 SSR,那么它们是怎么支持的呢...
Server端使用 StaticRouter
来得到路径(因为Server没有history这些)
app.get("*", (req, res) => {
const content = renderToString(
<StaticRouter location={req.path}>
<Routes />
</StaticRouter>
)
// ...
});
需要满足以下几点:
看看 Next.js 里面的 getServerSideProps
方法:
export async function getServerSideProps(context) {
const res = await fetch(`https://...`)
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: {}, // will be passed to the page component as props
}
}
只要组件里包含了 getServerSideProps
,那么就可以把数据作为 props 传到组件里
可以导出一个 loader 函数,在组件里可以使用 useLoaderData 来获取数据
export function loader() {
let res = fetch("https://api.gitub.com/gists");
return res.json();
}
export default function GistsRoute() {
let gists = useLoaderData();
return (
<ul>
{gists.map(gist => (
<li>
<a href={gist.html_url}>{gist.id}</a>
</li>
))}
</ul>
);
}
一些关键信息摘录
老的 SSR 会按 fetch - server render - client - hydration 4个步骤执行,只有前一步完成才能继续下一步。
而新的架构可按 <Suspense>
划分应用,不用等到所有部分好了才能看到。
Streaming HTML 技术可以先把部分页面发送到客户端,然后等到其他部分好了再重新发生过去,客户端负责插入到页面上。 举个例子,假设文章里有些评论,但是评论加载比较慢,可以先把评论用 Suspense 包裹,那么 React 就能先发送占位符,等到评论加载好了再发送过去。
Selective Hydration 技术可以让页面先部分 hydration。如之前的例子,假设评论没有加载好,页面也能交互~
1 多用用 Suspense 2 fetch 放在相关组件里
React 现在鼓励 ssr 了,得了解下原理,找了几篇文章看看:
SSR流程:
关于前面文章里提到的视频教程,可以到B站上搜搜
2022 更新