前言
最近在研究SSR服务端渲染,NextJS 算是比较经典的框架了,所以了解了解其用法对SSR或许能加深理解。如果能了解其实现原理,那就更好了。
服务端渲染
简单理解就是:你访问网页的时候,会一次性把完整的HTML返回给你。区别于 React,Vue 项目,HTML 文档只是一个壳子,需要运行 js 才能得到首屏的 Dom。
简介
Next.js 是一个轻量级的 React 服务端渲染应用框架。
Get Started
初始化项目,安装 next
1 | npm install --save next react react-dom |
将下面脚本添加到 package.json 中:
1 | { |
新建 ./pages/index.js 到你的项目中:
1 | export default () => <div>Welcome to next.js!</div> |
运行 npm run dev 命令并打开 http://localhost:3000。 如果你想使用其他端口,可运行 npm run dev -- -p <设置端口号>.
如何使用服务端渲染?
默认支持服务端渲染,获取网络请求写在 getInitialProps 内部,就可以在 render 中获取数据,直接渲染。
1 | import React from 'react' |
原理
应用入口
使用了 node command line,能让我们仅仅写了 page 的代码,就能让整个应用跑起来。以至于我们都找不到入口。nextjs 真的是很厉害~封装的很好
可以看到,当我们使用 yarn start 的时候,应用执行了 next-start
1 | const commands: { [command: string]: () => Promise<cliCommand> } = { |
next-start 开启了一个服务
1 | startServer({ dir }, port, args['--hostname']) |
startServer 的实现,获取 next 实例,然后使用 http 创建服务,主要的请求逻辑的代码都在 next 的 getRequestHandler 里面
1 | export default async function start( |
handleRequest 处理请求
1 | private handleRequest( |
run 获取 route 实例并进行处理
1 | protected async run( |
router 是在项目初始化的时候进行创建的,其中一个就是根据,默认都会有很多路由处理器
1 | protected generateRoutes(): Route[] { |
默认页面路由都是走到最后,也就是执行 render,获取渲染的 html
1 | public async render( |
其中 renderToHTML 实现了具体逻辑,通过 sendHTML 返回页面 HTML
renderToHTML 实现,首先通过 findPageComponents 获取路由具体页面 Compenent,然后使用renderToHTMLWithComponents 进行 React 转换为 HTML
1 | public renderToHTML( |
renderToHTML,在 renderToHTMLWithComponents 内部执行
省略了很多代码,为了了解主要逻辑。
首先会执行 loadGetInitialProps,也就是业务代码中的 props 获取,运行在服务端。
然后使用 Document 的 getInitialProps 创建 Document,并把 component 赋值,获取最终的 html
1 | export async function renderToHTML( |
使用 renderElementToString 渲染获取 html
1 | function render( |
到这里基本就结束了
Nextjs 还可以有很多自定的东西,与 koa,express 结合~
参考
后续
博大精深啊