一 对同构的大体理解
将浏览器的dom加载和数据加载分开执行。复制代码
二 为什么要同构
- 便于web应用的SEO
- 提升用户体验(渲染快嘛
- 前后端一些代码统一(后面的通过redux实现前后数据互通可略微代表一哈)
三 怎么同构
客户端
最终效果是用户看到我们的web应用和访问其他web应用一样,打开浏览器输入网址 回车出现web应用首页的样子。那没什么难的 搭个react项目 EZ是吧 (太多脚手架 网上demo 好坏都有 照葫芦画瓢都能搭出来是吧) 基本用到的技术栈: react react-router 4.x react-redux redux webpack4.x
客户端结构
简单解释下
actions
存放actioncreator的目录componets
存放用到的自己编写的组件类config
存放webpack的dev和prod的配置 且含一个用于本地跑webpack-devserver的服务文件 具体配置就不贴了dist
webpack打包生成的目录reducers
存放处理各种action的reducerstore
创建store目录app.js
项目入口 reactDOM.render那个地方routes.js
项目路由
服务器端
坑1:关于express
路由和react-router
统一的问题
网上大多数demo的例子是比较老的所以用到的是老版本的react-router
的方式做的 用到了match方法 但是对于4.0以后的版本不适用 所以看了下官方api 是用了staticRouter
来代替原来的 browser/hash
按照官方的demo改了下 就跑通了
renderToString
是同构的核心。其实很简单,打印下html就是字符串是吧。然后服务器调用 res.write
返回给浏览器就完成了同构的第一步。 坑2:忽略服务器渲染导致组件生命周期未走全的问题
回到客户端想给一个组件绑定事件及获取绑定ref
的节点获取不到 查了下是由于 服务器渲染只会走render前的生命周期 那么当我们的节点还未挂在到dom上 给他绑定事件和获取都肯定是不行的。这就说通了是吧
那么按我的理解是还需要在rendertostring
的模板html(可通过设置其他模板改为ejs都行 不冲突)里 添加我们通过webpack
打包生成的bundle.js(webpack
用到SplitChunks
的话生成的其他类似ventor的文件块也要引入) 因为什么呢? 我的理解是用户打开浏览器后加载bundle.js然后 去将服务器渲染时候未走过的生命周期 走一遍 。(未绑定成功的事件和获取节点就变得可行了) 然后就是通过配置线上和测试环境(忘说了服务器这边用到的是express nodemon mongodb
)
以上的内容仅是2天的尝试搭建后的心得体悟 对于刚接触同构的兄弟们具有一些提示作用。其实想要服务器渲染完全可以用下next.js
我自己也是在2天的搭建后 尝试了用下next.js
进行同构 感觉实在太方便了 而且用pm2进行服务器的部署及Nginx
配置都有详细的文章可参考。感兴趣的可以尝试下。