从Next.js到服务端渲染的学习

在next.js里提供了一个静态异步方法:getInitialProps,它能异步获取JS普通对象并绑定在props上,通过这个方法我们就可以在服务的获取接口数据。
static async getInitialProps({ req }) {
console.log(req)
return {}
}
复制代码观察上面代码,会发现还有一个req对象,它指代的为服务的的request对象,但是作为一个前后端分离的独立前端工程,并没有与服务端有这方面的互动。但是在传统的react项目中,获取接口数据一般使用componetDidMounted,在Next.js我们仍然可以使用它,由于这个函数只存在于客户端,继续使用componetDidMounted可能会失去SSR应用的灵魂。
Next.js + Mobx ?
如果我们项目中使用了Mobx进行状态管理,如何在getInitialProps里面进行"dispatch"呢,注入到this.props呢,当然这是不可以的,因为getInitialProps是一个静态方法,无法使用this这一对象。这时候若你非要结合Next.js与Mobx,那你可能不能使用getInitialProps,而使用componetDidMounted了,或者你只能单页面单store。
二、Next.js怎么配置
Next.js 是react进行服务端渲染的一个工具,默认以pages为渲染路由的路径。
如何对next.js做一些配置呢?有两种方式,方法一:在根目录的next.config.js里进行配置;方法二:自定义一个server.js。
next.config.js
可以使用BundleAnalyzerPlugin对webpack进行相关配置,如
const { BundleAnalyzerPlugin } = require(‘webpack-bundle-analyzer’)

module.exports = BundleAnalyzerPlugin({

})
复制代码server.js
新建Next的入口文件server.js里,实现app.prepare方法,利用该方法可以做一些前置工作。如果服务端使用的是express,可以自己控制路由:
const app = next({ dev })

app.prepare()
.then(() => {
const server = express()
server.get(’/page/:id’, (req, res) => {
const page = ‘/pageXX’
const params = { id: req.params.id }
app.render(req, res, page, params)
})
})
复制代码或者使用http.createServer创建一个服务器,做一些前置配置工作,如多语言配置。
其实,在Next.js内部也是新建了一个Node Server,利用这个Server类完成完成大部分的渲染工作,不仅仅如此,这个类还有组件渲染,路由匹配,错误处理,缓存处理等多个环节。当然要理解源码的渲染机制,Node知识必不可少,这里就不深入(其实不会)了。
三、自己怎么实现一个服务端渲染

这里是仓库地址:最简单服务端渲染项目

这里是仓库地址:react服务端渲染

这里是仓库地址:最简单的react,客户端服务端同构

1.构建编译与运行环境
安装babel-node:npm install bable-cli -g;
安装编译的react需要的组件:
npm install babel-preset-react -S
npm install babel-preset-env -S
npm install babel-plugin-transform-decorators-legacy -S
复制代码在package.json设置命令启动命令:
corss-env NODE_ENV=test nodemon --exec babel-node src/server.js
复制代码其中cross-env勇于设置环境变量;nodemon监视文件的改变并重新运行命令。
在.babelrc配置Babel(基本用法和格式),那么可以做以下配置:
{
“presets”: [
“env”,
“react”
],
“plugins”: [
“transform-decorators-legacy”
]
}
复制代码2.书写服务server.js
新建server.js,完成第一个实验:
import express from ‘express’
var app = express()
app.get(’/’, (req, res) => {
res.send(‘

hello express

’)
})
app.listen(3000, function() {
console.log(‘server started !’)
})
复制代码启动命令,访问localhost:3000
npm run server
复制代码
这里是仓库地址:最简单服务端渲染项目

3.React组件如何实现渲染
首先有两个方法了解以下

renderToString:将 React Component 转换为HTML字符串,生成的DOM会带有额外的属性:每个DOM会有data-react-id属性,第一个DOM会有data-checksum属性。
renderToStatucMarkup:将 React Component 转换为HTML字符串,但不会有额外的属性。

例如想要对React进行渲染,需要把组件转换为HTML,使用renderToString方法:
server.js:
import App from ‘./components/App’
import React from ‘react’
import {renderToString} from ‘react-dom/server’

var app = express();

app.get("/", (req, res) => {
const list = [1, 2, 3, 4, 5]
const html = renderToString()
res.send(html)
})
app.listen(3000, function () {
console.log(‘server start !’)
})

复制代码App.js:
import React from ‘react’

export default class App extends React.Component {
render() {
return(



    {
    this.props.list.map(item => {
    return
  • {item}

  • })
    }


)
}
}
复制代码访问localhost:3000即可得到下面结果:

https://www.jianshu.com/p/65f42bd316bb
https://www.jianshu.com/p/205c601a5949
https://www.jianshu.com/p/3dee4e87a2da
https://www.jianshu.com/p/027d6c6540ac

这里是仓库地址:react服务端渲染

4.react同构渲染
做到以上React的渲染,只能做到服务端渲染,客户端的渲染还没有实现。而同构的含义是:客户端和服务端使用相同的组件,服务端负责首次渲染,行为和交互由客户端进行。
接下来我们使用React同构渲染一次:

使用create-ract-app脚手架创建react工程
结合express和create-react-app的配置文件
将create-react-app编译打包后的文件通过express公开出来:app.use(’/’, express.static(“build”))

import express from “express”
import App from ‘./App’
import React from ‘react’
import {renderToString} from ‘react-dom/server’
import fs from ‘fs’

var app = express();

app.get("/", (req, res) => {
const html = fs.readFileSync(’./build/index.html’)
const content = renderToString()
res.send(html.toString().replace(’

’, <div id="root">${content}</div>))
})

app.use(’/’, express.static(‘build’))

app.listen(3000, function () {
console.log(‘server start !’)
})

复制代码上述描述的步骤是先生成build文件,然后服务器将生成的build文件替换成已有的html,发送到客户端,这样客户端与服务端内容将保持一致。
如何得到结果:首先执行npm run build生成build文件,然后运行npm run server访问localhost:3000

发布了62 篇原创文章 · 获赞 0 · 访问量 5703

猜你喜欢

转载自blog.csdn.net/chunzhenwang/article/details/104348319