最小而美的Egg + React + SSR 服务端渲染应用骨架

网友投稿 746 2022-10-23

最小而美的Egg + React + SSR 服务端渲染应用骨架

最小而美的Egg + React + SSR 服务端渲染应用骨架

简体中文 | English

Egg + React + SSR boilerplate

最小而美的服务端渲染应用模板,特点

小:实现方式简洁,生产环境构建出来的 bundle 为同等复杂度的 next.js 项目的 0.7 倍,生成文件数量相比于 next.js 减少非常多全:支持 HMR,支持本地开发以及生产环境 CSR/SSR 两种渲染模式无缝切换,支持定制组件的渲染模式,同时支持 TypeScript 版本美:基于React和Eggjs框架,拥有强大的插件生态,配置非黑盒,方便加入当前业务的个性化逻辑

正在使用这个项目的公司(应用), 如果您正在使用但名单中没有列出来的话请提 issue,欢迎推广分享

如果是 Serverless 环境,推荐同样写法但基于 Serverless 端渲染规范的实现 https://github.com/ykfe/ssr

快速入门

这里我们提供了一个脚手架,方便你创建快速项目。

$ npm install yk-cli -g$ ykcli init $ cd $ npm i$ npm start$ open http://localhost:7001

在执行 ykcli init 的时候,可以选择 javascript 或 typescript 语言,非常方便。

npm scripts

1)启动服务

启动监听 7001 端口,此端口同时用于服务端渲染以及客户端渲染,通过 query 或者 config 来指定渲染模式

$ npm start # 建议以本方式启动应用,同时启动服务端渲染 + 客户端hydrate

2)只启动服务端渲染,此时仅服务端直出 html,没有与客户端混合的步骤

$ npm run ssr

3)启动客户端渲染

仅限于本地开发使用,启动监听 8000 端口,只启动客户端渲染,相当于传统的 cra 脚手架开发模式

$ npm run csr

4)配套的脚本

$ npm run prod # 使用egg-scripts模拟SSR应用生产环境,如无特殊定制要求生产环境可以用该方式启动$ npm run build # 打包服务端以及客户端资源文件$ npm run analyze # 可视化分析客户端打包的资源详情

功能/特性

该模板特色为:写法简单、功能强大、一切都是组件、支持 SSR/CSR 两种渲染模式无缝切换。

更多功能/特性如下:

基于 cra 脚手架开发,由 cra 开发的 React App 可无缝迁移,如果你熟悉 cra 的配置,上手成本几乎为 0 小而美,相比于 beidou,next.js 这样的高度封装方案,我们的实现原理和开发模式一目了然 推荐使用 egg 作为 Node.js 框架但并不强制,事实上你可以发现几乎无需做任何修改即可迁移到 koa,nest.js 等框架 同时支持 SSR 以及 CSR 两种开发模式,本地开发环境以及线上环境皆可无缝切换两种渲染模式 统一前端路由与服务端路由,无需重复编写路由文件配置 支持切换路由时自动获取数据 支持本地开发 HMR 稳定性经过线上大规模应用验证,可提供性能优化方案 支持 tree shaking,优化构建 bundle 大小以及数量 支持 csr/ssr 自定义 layout,无需通过 path 来手动区分 抛弃传统模版引擎,拥抱 React 组件,使用 JSX 来作为模版 独创最佳发布实践,让你更新页面无需重启应用机器 配套结合antd的 example 的实现 配套结合react-loadable做路由分割的 example 的实现 配套结合dva做数据管理的 example 的实现 配套结合ssr-with-multipage多页面应用的 example 配套结合Rax版本的实现 配套TypeScript版本的实现

结合 Serverless

我们在 Serverless 场景下的SSR 框架已经正式发布,如果你更喜欢平滑开箱即用体验的更高层次解决方案并且希望能够快速部署。推荐使用该框架进行开发。与本项目不冲突,互相补位

写法

在写法上统一 csr 和 ssr,采用 next 类似的静态的 getInitialProps 作为数据获取方法

function Page(props) { return

{props.name}
}Page.getInitialProps = async (ctx) => { return Promise.resolve({ name: 'Egg + React + SSR', })}export default Page

具体说明如下。

render 是 React 的视图渲染方法getInitialProps 是获取数据方法,将返回值赋值给组件状态 csr 通过高阶组件实现ssr 通过 Node 执行

在运行时,通过npm run csr和npm run ssr来进行区分,是目前最简单的同构渲染方案。当页面初始化加载时,getInitialProps 只会加载在服务端。只有当路由跳转(Link 组件跳转或 API 方法跳转)时,客户端才会执行 getInitialProps。

getInitialProps 入参对象的属性如下:

ctx: Node 应用请求的上下文(仅在 SSR 阶段可以获取)Router Props: 包含路由对象属性,包括 pathname 以及 Router params history 等对象,详细信息参考 react-router 文档

一切皆组件

我们的页面基础模版 html,meta 等标签皆使用 JSX 来生成,避免你去使用繁琐的模版引擎语法

const commonNode = (props) => // 为了同时兼容ssr/csr请保留此判断,如果你的layout没有内容请使用 props.children ? { props.children } : '' props.children ? (

Egg + React + SSR
by ykfe

{props.children}
) : ( '' )const Layout = (props) => { if (__isBrowser__) { return commonNode(props) } else { const { serverData } = props.layoutData const { injectCss, injectScript } = props.layoutData.app.config return ( React App {injectCss && injectCss.map((item) => ( ))}
{commonNode(props)}
{serverData && (