全干工程师的自我修养 前后端一体的启动模板

项目动机

从前到后走一套是一直想做的事情,于是利用这次长假搭建了一个基于 TypeScript 的前后端一体的项目启动模板。即作为自我学习练手,也方便自己之后搭建项目。

概括来说是一个 React + Express + MongoDB 的项目。为了挑战自我,这一次刻意挑选掌握还不全面的 TypeScript,前端方面使用了 styled-component 来进行样式的编写,前后端交互使用 GraphQL 来代替传统的 RESTful 架构。不得不说,熟练度不够外加踩新坑,让搭建初期痛不欲生,甚至几度想放弃。好在风雨之后终见彩虹,项目跑起来之后,感觉自己对 TypeScriptGraphQL 也有了一定的认识。

本文从项目角度进行整体介绍,踩过的坑的细节以及搭建中遇到的问题会另写文章单独展开。

Demo 展示

整个项目是一个启动模板。因为后台系统的通用度相对较高,并且自己也较为熟悉,因此作为本项目的前端页面。当然前端是怎样的都可以。

项目 GitHub 地址: Faiz Admin。启动可以参考项目中的 README。

欢迎小伙伴 clone 下来跑一下,也欢迎 Star,交流,建议,指正。(_在思考项目名的时候,恰巧看到了堆着的假面骑士 Faiz 的模型,便以此为项目名。_)

在介绍项目之前,可以先来看一下项目的页面。因为只是模板项目,所以在功能上仅实现了登录、登出、用户以及角色的添加和查询等最基础(通用)的功能。毕竟实际工作中需求多种多样,需要具体情况具体应对了。

登陆页
内容页

技术栈梳理

从前到后涉及的知识面比较广泛,所以将本项目主要的知识点整理成下面的导图方便梳理。技术栈更多的是个人的喜好,前后端的框架均可以换成自己顺手的框架。

涉及技术导图

项目语言:TypeScript

采用 TypesScript 的好处已经不用赘述。尽管在代码量上会因为 interface 的关系会增加不少,以及刚上手时把人折磨得半死的类型提示错误,但在 Debug 上会轻松许多,大多的 Bug 都偏向业务逻辑,而语法上的错误基本没有了。

目前主流框架都已支持 TypeScript (Vue 3.0 将完全支持),从面向简历编程的角度来说也应该学习起 TypeScript 了。只要躺过了类型错误的坑,coding 就会舒服很多,TypeScript 的强类型也迫使在写代码时要思考的更加严谨。(可以多利用一下 VSCode 的提示)

前端框架:React

三大主流框架中选择 React,主要还是隔个人喜欢函数式自由的风格以及 Hooks,在本项目中也基本都使用 Hooks。UI 方面,Material UI 太依赖与 Google Font 和 Icon,对于国内来说可能不太方便;微软的 Fabric UI 浓浓的 Office 风格,很多组件还是需要自己进行封装。所以最终还是选择回了 antd。

在状态管理方面,实在不愿意去手写 actionreducers,于是使用了 mobx。这样就能在一个 class 中完成数据状态的管理了。没有了 actionreducer,代码也干净很多。另外封装了一个全局 loading 来实现类似 dvaloading.effects[xxx] 的效果。

与后端通信方面以 ApolloClient 和 Axios 结合使用。ApolloClient 是比较常用的 GraphQL 客户端,与服务端的 ApolloServer 配套(其实分开使用也没事),主要负责 GraphQL 部分。Axios 用来负责 RESTful 的接口,用于不需要权限的 api,如 /login。这里的划分主要和 GraphQL 的鉴权机制有关。

后端框架:Express + ApolloServer

Express 一定不会陌生,最早出现的服务器框架,插件丰富第三方支持也很不错。这一次使用的 Apollo Server、TypeGraphQL 都主要以 Express 为例子。文档上的支持越好,后期 Debug 时也越方便。后端这边最大变化就是引入了 ApolloServer 以及 GraphQL 相关的功能。剩下的其实和正常的后端服务器完全相同。

数据库:MongoDB

在数据库方面,这次采用了 MongoDB。一方面是现在工作中使用,另一方面搭建起来简单,直接使用 Docker 即可。

数据库的 ORM 毫无意外的就是 Mongoose,本项目自然用的是 TypeScript 版本的 TypeGoose,并且可以与 TypeGrahQL (定义 GraphQL Schema 类型的库)的 Schema 可以公用,能有效减少重复 coding。毕竟 Mongoose 的 Schema 在一定程度上和 GraphQL 的 Schema 有关联。要维护两份相同的文件简直就是噩梦……

目录结构

在上面简单地介绍了一下技术栈,接下来就来看一下项目的目录结构。

整个项目划成 frontendserver 两部分,即前端和服务端。使用 TypeScript 后会有许多 interface,关于 interface 是统一放到一个文件夹中管理还是分散在文件中这个问题一直困扰着我。在这个项目里面主要还是分散在各个文件中自行管理(尽管建了最外层文件夹)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
.
├── frontend // 前端工程文件
│   ├── config // 全局配置文件
│   │   └── index.ts
│   ├── index.html
│   ├── locale // 国际化文本文件
│   │   └── zh_CN
│   ├── package.json
│   ├── public // 静态资源文件
│   ├── src
│   │   ├── client.ts // ApolloClient
│   │   ├── constants // 常量文件夹
│   │   ├── global.d.ts
│   │   ├── index.tsx // 入口文件
│   │   ├── interface // interface 文件夹
│   │   ├── pages // 页面文件夹
│   │   ├── service // 处理 effects 以及 Query 语句
│   │   ├── store // mobx store 文件
│   │   └── utils // 工具函数
│   ├── tsconfig.json
│   ├── webpack
│   │   ├── webpack.config.js
│   │   └── webpack.dev.config.js
│   └── yarn.lock
└── server // 服务端工程文件
├── config // 全局配置文件
│   └── index.ts
├── database.ts // 数据库链接 (Mongoose)
├── dbInit.ts // 数据库初始化文件
├── index.ts // 入口文件 Express + ApolloServer
├── logger // 日志存放文件夹
├── nodemon.json
├── package.json
├── src
│   ├── constants // 常量文件夹
│   ├── controller // 数据库 CRUD 操作部分
│   ├── graphql // GraphQL 的 Schema & resolver,GraphQL 与 Mongoose 的 Schema 可以公用
│   ├── router // 路由文件,处理 RESTful 的接口
│   └── utils // 工具函数
├── tsconfig.json
└── yarn.lock

更进一步

现在的模板项目中已经涉及了很多知识与框架,但严格来说还有更进一步的空间。

大部分集中在服务端,比如日志管理模块(log4js);服务启动后用于监视的 pm2;可以增加 Redis 来缓解数据库压力;多个服务之间通信的消息队列……总之,能更进一步的空间还有很大。

关于日志以及 pm2 的部分将会是接下来打算做的部分。


全干工程师的自我修养 前后端一体的启动模板
https://konta9.github.io/2020/02/24/2020/全干工程师的自我修养 前后端一体的启动模板/
作者
Konata
发布于
2020年2月24日
许可协议