【serverless实战】腾讯云·云开发+nextjs(SSR or 静态导出)实现官网动态化

2020-05-06 23:36:16 浏览数 (1)

背景

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 来进行网络请求,理由如下:

  • 完美支持 ssr、node、browser 环境:直接用于 getInitialProps 钩子
  • 支持一级代理转发:可以在内网环境下获取外部数据

http 触发调用云函数

由于无法使用 tcb-js-sdk 和 tcb-admin-node,所以没办法通过 sdk 提供的 api 来读取云数据库的数据。

所以只能“曲线救国”,借助云函数 http 触发功能来获取云数据库的数据:

  • 在 cloudbase 控制台编写用于读取数据库的云函数
  • 开启云函数的 http 触发:调用者可以通过 http url 的方式调用云函数,传入参数,获取云函数运行结果
  • 在 getInitialProps 钩子中,使用 axios 调用远程云函数,获取最新数据

部分代码实现

在需要动态化内容的页面组件中,添加 getInitialProps 钩子,里面通过 axios 触发云函数,获取云函数数据,并将其挂入组件的 props 中。

组件内部根据 props 的内容,生成对应的 jsx 结构。

代码实现如下:

代码语言:javascript复制
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
    }
}

Q:为什么不选择 SSR,而是使用静态导出?静态导出怎么保证实效性?

理论上来说,SSR 是 SEO 获取最新数据的理论最优方案。但是考虑到云函数搭配 ssr 存在冷热启动问题,而静态导出后的文件直接部署到云开发静态网站服务上,本质上是对象存储,访问速度更快,并且节省费用。

除此之外,借助 CI 工具,设置了定时构建,以获取最新数据进行更新。如果有紧急情况,开发人员也可以在平台手动触发 CI,获取实时最新数据。

一句话,最合适的方案不一定是最优的

0 人点赞