www.cloudbase.net 云开发网站是基于 nextjs 开发,里面的内容是写在 js 配置文件。每当更新网站内容,都需要提交 git,并且本地进行静态导出,再借助腾讯云云开发的 cli 工具,部署到云开发控制台的「静态网站」服务。
但是内容的更新,不应该涉及到 git 记录(只包括代码或者配置的改动),而且每次改动都要手动 pull/push/deploy 一遍,属实麻烦。因此,需要进行动态化。
利用 nextjs 提供的 getInitialProps 钩子,从 cms 系统对应的云数据库中拉取动态内容。并将最新的内容,结合模板代码导出为静态 html 文件。
在 getInitialProps 钩子中,环境既不是 browser,也不是 nodejs,而是 ssr 的环境。所以无法使用 tcb-js-sdk 以及 tcb-admin-node 这两个库来获取云开发的数据。
这里使用了 axios.js 来进行网络请求,理由如下:
由于无法使用 tcb-js-sdk 和 tcb-admin-node,所以没办法通过 sdk 提供的 api 来读取云数据库的数据。
所以只能“曲线救国”,借助云函数 + http 触发功能来获取云数据库的数据:
在需要动态化内容的页面组件中,添加 getInitialProps 钩子,里面通过 axios 触发云函数,获取云函数数据,并将其挂入组件的 props 中。
组件内部根据 props 的内容,生成对应的 jsx 结构。
代码实现如下:
const MainPage = ({activities, courses, articles}) => {
// ...
return ()
}
Main.getInitialProps = async () => {
const promises = [
getActivities(),
getCourses(),
getArticles()
]
const [
activities,
courses,
articles
] = await Promise.all(promises)
return {
activities,
courses,
articles
}
}
理论上来说,SSR 是 SEO+获取最新数据的理论最优方案。但是考虑到云函数搭配 ssr 存在冷热启动问题,而静态导出后的文件直接部署到云开发静态网站服务上,本质上是对象存储,访问速度更快,并且节省费用。
除此之外,借助 CI 工具,设置了定时构建,以获取最新数据进行更新。如果有紧急情况,开发人员也可以在平台手动触发 CI,获取实时最新数据。
一句话,最合适的方案不一定是最优的。