koa+ts搭建ssr后端
前言
此文为ssr三步曲的第三部,前文在这
这篇文章的代码有2个分支:tag-v3-pre、tag-v3
搭建步骤
之前写过一篇文章,koa+mongodb搭建后端,里面写的更详细一些,有兴趣的可以翻出来看看,只不过文末一部分一直搁置未完篇,因为一行行写起来比较繁琐,后面又比较忙。(说白了,是懒,哈哈)
此处我们简单一点,用koa+koa-router搞一个后端路由出来即可,话不多说,那就开始吧。。
安装依赖
npm i koa @koa/router koa-bodyparser koa-static art-template koa-art-template log4js chalk
node端的模板引擎推荐art和nunjucks,art简洁、速度快,而nunjucks属于富功能模板引擎,功能更加强大,有layout、block、全局函数/变量、模板继承等等。
不过事情刚开始嘛,我们的需求是很简单的,杀鸡焉用牛刀,所以选择art
@koa/router,是koa团队接手了koa-router之后维护的类库,koa-router停留在了7.x,而@koa/router也是直接从8.x开始
log4js: 日志是少不了的,所以log4js来一个吧
chalk: 让控制台输出更漂亮
再安装一下types
npm i -D @types/koa @types/koa__router @types/koa-bodyparser @types/chalk
接下来就不贴具体的代码了,只阐述一下思路,代码在github上有按分支存档,文中会对应说明
如何运行
如果是普通nodejs,我们可以用nodemon+ts-node来调试:
npm i ts-node
// nodemon很多地方用的上,所以直接全局安装吧
"devServer": "nodemon --watch src -e ts,tsx,js,json --exec node --inspect=127.0.0.1:9229 -r ts-node/register ./src/server/app.ts",
最简单的一个例子就是koa路由里,使用renderToString,来渲染一个jsx,返回渲染后的string给前端。
但如果直接运行的话,是会报错的,因为有以下几个问题需要解决:
- nodejs不支持import/export语法
两个方案:
- 使用babel转,速度会拖慢
- node9开始多了一个特性:--experimental-modules,node运行的时候启用这个选项,并且文件名需要为.mjs后缀
- nodejs不支持tsx语法
- 组件内部导入scss之类的文件在node端会报错
- 打包出来的js, css如何注入
- 服务端数据如何注入到客户端
node是没办法对tsx, scss之类的做处理的,所以,webpack登场了,除了前端代码,后端代码同样需要用webpack来进行打包,主要有以下几点区别:
webpack:
- webpack的target需要设置成node
- css、scss使用ignore-loader忽略掉
- 使用loadable来拆分文件、做服务端渲染
loadable真是神器,没有这个的话,就只能用manifest loader来生成资源清单,并且没有拆分功能
- 服务端数据注入到客户端比较简单了,直接往window对象插入一个对象,比如ssrData = {},然后前端初始化store的时候合并一下initState即可
初始版本
总的来说,我们需要跑3个命令:
- 编译客户端并watch
- 编译服务端并watch,服务端对client端生成的文件做静态资源处理
- 用nodemon之类的工具,watch服务端生成的文件,有变更时自动重启
到这里,其实生产环境的ssr已经完成了,因为ssr我们就是对客户端、服务端分别进行打包,然后node运行服务端的代码启动服务。
这个版本的代码详见:https://github.com/Thyiad/react-ssr/tree/tag-v3-pre
进化版本
上一个版本在生产环境没问题,开发环境简直不能忍啊。因为css更新不会自动刷新、js更新不会自动刷新,干啥都需要手动刷新一下浏览器。。
所以我们想办法改良一下,用一个脚本解决,这个命令干了这两个事情:
- webpack编译客户端,并手动启一个webpackDevServer
- webpack编译服务端,并监听hooks.done,在done之后启一个node,启动服务
启动新进程可以用child_process.spawn或者cluster,此处我们使用child_process即可。
cluster是基于child_process.fork启动若干子进程,再有一个agent来调配,通过IPC通信,功能更强大,但貌似官方其实不是很推荐,我看到生产中更多人选择的是pm2等工具。
就算css变更也同样会触发hooks.done,所以我们改进一下,nodemon只监听后端生成的js,有变更才杀掉旧的子进程,启动一个新的子进程
这个版本同样进行了一些其他的优化,比如把配置文件提取到一个create-config.js中,客户端服务端都调用该函数生成config。同时命令简化成2条,dev和build分别用来启动本地调试和打包生产代码。
这个版本的代码详见:https://github.com/Thyiad/react-ssr/tree/tag-v3
还欠缺的
- 前文中所述的服务端数据注入到客户端、服务端获取数据
这两个其实都比较简单,所以只加了todo备注,没有填充代码
- ui库加入
比如可以加入ant design,还有最近发现微软的fluentui也不错,感觉可以后面试用一下
- 封装成一个cli工具
在上述完善后,可以封装一个cli工具,支持生成spa、ssr、不同ui的项目代码
小结
整个过程其实也踩了不少坑,webpack的配置还是挺多的,不过只要你耐心根据需要把官网文档翻一遍,基本上也没啥问题。
上次看到有人开玩笑说现在多了一个工种:webpack配置工程师..
vue生态的vite最近更新特别频繁,等稳定下来可以尝试一下,这些工具都是一代比一代简化,希望以后在配置方面能更简化、节省精力吧。。