ssr知识汇总
查看是不是服务端渲染 右键查看源码 有值就是服务端渲染 没有就是客户端渲染
把react组件 变成字符串 放在浏览器
import . {renderToString} from 'react-dom/server'
let html = renderToString(<Home />)
<div id="root">${html}</div>
打包编译
cnpm i webpack-node-externals
node核心模块
const nodeExternal = require('webpack-node-externals')
fs模块不需要打包进去
webpack.config.js中配置
externals:[nodeExternal()]
// 负责检测所有引入的核心模块 不要打包到server.js中
target:"node" // 告诉webpack 打包的node目标环境
cnpm i npm-run-all -g
dev:start:"nodemon build/server.js"
监听文件变化 自动启动服务
dev:"npm-run-all --parallel dev:**"
批量执行脚本
在react 组件中直接写
state = {
number:1
}
需要安装一个插件
cnpm i @babel/plugin-proposal-class-properties
plugins:["@babel/plugin-proposal-class-properties"]
等同于constructor(){
this.state = {
number:1
}
}
点击没有反应 服务端渲染 组件中加上事件不起作用
服务端渲染搞不定事件
服务端渲染处理首屏dom结构渲染
其他的都是客户端渲染
<script src = ''/client.js ">
</script>
服务端写一遍 客户端 一模一样写一遍
client.js 就是客户端打包出来的内容
webpack.client.js
webpack.server.js
webpack.base.js 基础配置 共享代码
const merge = require(''webpack-merge")
app.use(express.static(path.resolve('public'))) public目录作为静态资源的根目录
服务端渲染一遍了 react就不能render了 使用hydrate结构就不变了 直接完成绑定
react.hydrate(<Counter />,document.getElementById('root'))
不需要客户端路由了 服务端把路由匹配好
访问谁 就是返回谁的dom结构
server中写
import {StaticRouter} from 'react-router-dom' 静态路由容器 用于服务端
写在路由里面
let html = renderToString(<StaticRouter context={{}} location = {req.path}>
{routes}
</StaticRouter>)
子组件可以拿到context 。 通过this.props.staticContext
import React,{Fragment} from 'react'
一个router只能放一个child 用Fragment包一层
客户端和服务端代码一定要统一
import {Provider} from 'react-redux'
<Provider store = {store}></Provider>
客户端的仓库和服务端的仓库不一样
getServerStore
getClientStore
拆分一个render.js
第三个了
http://www.javascriptpeixun.cn/my/course/2056
异步数据处理
服务端解决跨域的中间键
let cors = require('cors')
app.use(cors({
origin:"http://localhost:3000"
}))
不要直接访问api服务器 权限无法做
代理服务器做鉴权
服务端渲染出带着数据的仓库 然后渲染 这个怎么做 异步的
等他取回来 我再渲染
获取要渲染的组件routes
routes导出的是一个数组
import {staticRouter,matchPath} from 'react-router-dom'
兼容所有的情况 不能用req.path === route.path进行判断 匹配不准确 :id
dispatch的返回值就是派发的action
thunk中间件执行了这个
核心源码
数据完成后再renderToString
如果服务端渲染过数据了 那么客户端就不渲染数据了
服务器仓库和客户端仓库不是一个仓库 客户端仓库的list 是0 所有进入函数了
服务端仓库和客户端仓库要同步
发送给客户端
依赖关系的处理
多级路由
app.js 把客户端和服务端共用的模板放在一个文件中
子路由 子组件还有子组件 多级路由的渲染
cnpm i react-router-conifg 处理多级路由的匹配和渲染
处理嵌套路由
node代理服务器
客户端访问的是3000 端口 node服务器资源 服务端访问4000端口
thunk携带额外的参数
这样 这里就多了一个参数
代理服务器
import proxy from 'express-http-proxy' 代理到这机器上
app.use('/api',proxy('http://127.0.0.1:4000'))
代理解析器 类似重写路径
权限
用session 存储登录信息 需要引入session中间件
req.session.user = xxx
自动多一个cookie
node 中间层携带cookie 请求后端服务器
重定向处理
服务端style-loader使用
cnpm i isomorphic-style-loader
服务器是准备html的过程
服务器收集css代码 不用客户端执行css了 这样的话防止抖动的产生
高阶组件做样式统一处理
同构 客户端渲染 服务端渲染
nestjs 代码分割
访问哪个就是加载哪个
新建一个public文件夹 里面放图片 可直接访问这个图片
hapi
安装@zeit/next-css
next.config.js
css文件不做处理
高阶组件包一层就能拿到router了
dispatch 和 action 是息息相关的,只有通过 dispatch 才能发送 action。而发送 action 之后才会执行 subscribe 监听到的那些方法。
所以 dispatch 做的事情就是将 action 传给 reducer 函数,将执行后的结果设置为新的 store,然后执行 listeners 中的方法。
另一个是用 combineReducers 把多个 reducer 函数合并到一起。
https://zhuanlan.zhihu.com/p/50247513
form表单包一层 可以进行校验
初始化数据
动态加载dynamic组件
共享仓库
共享cookie