关于ssr相关的介绍,可以移步之前的一篇博文,本文不再赘述
日常工作中,我们可能都接触过ssr,不过我们可能通常是借助于框架(例如Next.js)的支持来完成ssr。今天我想尝试,摆脱高度封装的前端框架,只依赖react相关的库,来实现ssr。
本篇代码 pnpm i
安装依赖,npm run server
启动服务
环境:node 20.12.0 react和react-dom版本均为18.3.1
参考文献:知乎专栏:SSR原理与实践
正文
我们的目的,是本地的8080端口起一个node服务,然后当我们访问localhost:8080的时候,服务端能返回给我们一个页面,。在拿到页面之后,浏览器会对页面进行水合,从而使得页面可交互。
首先,我们先安装一下依赖。我比较喜欢pnpm(节省磁盘空间,避免幽灵依赖),所以我直接在命令行敲pnpm i react react-dom express
。安装react(将jsx转为虚拟dom),react-dom(将虚拟dom转成dom),express(用于起一个web服务器)
然后我们新建三个文件,分别是server.js,index.js,App.jsx
App.jsx里面,我们就简单实现一个组件吧,然后要用commonjs的方式去引入和导出(因为我们是极简版本,甚至都没有经过打包构建流程,为了能让node端识别,就直接按cjs规范写了)
index.js里面,我们要去写用于客户端执行的代码,我们暂且随便在里面console.log一句话吧,用于证明index.js被成功加载。
本期的重头戏来了,server.js,不多bb先上代码
1 | const express = require("express"); |
对于访问根目录的请求,我们依旧是通过cjs的require,拿到app.jsx的内容。然后借助react-dom/server的api renderToString
,将jsx组件转成html字符串 。
接下来就是拼模板啦,直接copy模板,然后把得到的html字符串放到模板字符串中间,并且在最后写一个script标签,加载未来可期的index.js。然后返回response就可以了
然后为了解决node不认识jsx的问题,我们又装了bable的一系列包。依旧是用pnpm安装@babel/cli,@babel/core,@babel/node,babel/preset-env,@babel/preset-react。然后在package.json添加一个script,
1 | "scripts": { |
然后我们就可以通过npm run server,来启动服务了。打开浏览器,访问localhost:8080,可以看到页面正常展示。但是打开控制台,发现index.js没加载出来,404了。是因为请求localhost:8080/index.js 这个静态资源路径,express是不知道你要什么的。需要通过express.static(pathxxx)
中间件,来告诉express,以pathxxx作为静态资源目录。例如我这里把index.js放在了根目录,那pathxxx就是“.”就可以了。
再次重启服务,打开控制台,看到index.js正常被加载,打印出了我们想要的东西。
本次暂时只实现服务端渲染的部分,后续客户端水合,且听下回分解