从零到一搭建一个React企业级项目
技术栈
文章中涉及的技术栈大致包含以下:
- React18:UI 框架
- TypeScript:类型语言
- Vite4:构建工具
- ReactRouter:路由
- zustand:状态管理
- ESlint,Prettier:代码规范
- Axios:请求
- antd:组件库
- TailwindCSS3:css 解决方案
- i18next,i18n-ally:多语言
- ahooks:工具方法库
- pnpm: 依赖管理
由于项目的规模、复杂性和要求都有所不一样,在技术选型上都会有所差异,我这边指出的是常见的后台管理类项目的需求架构。
技术选型是项目架构中占比比较大的一部分,下面简述一下,我是如何对比选择的技术栈:
React vs Vue
两者并没有谁好谁差的说法,一些论坛上吵来吵去谁也没办法说服谁。如果是个人项目,当然可以主观用哪个都是不错的,但从团队的角度,可能就需要考虑以下这些点了:
对 React 的掌握程度:至少要有一个核心成员熟练 React,避免出现有问题不知道问谁的情况。
前端团队成员的意向 or 招聘需求
设计趋向 antd or element,能复用就能提高开发效率
社区生态,例如你想要使用的必要的库只支持 React
TypeScript vs JavaScript
其实本质就是看对类型看不看重;
TypeScript 相对于 JavaScript 的优势在于它引入了静态类型检查,使得代码更加健壮和易于维护。
vite vs webpack
我个人有个项目是从 webpack 升级到 vite 的,升级成本并不高,一些项目甚至直接复制社区的最佳实践代码,稍加修改就能有不错的效果。
使用成本只是一个入门要求,只要能解决痛点,稍微学习一下当然值得。
vite 解决了什么问题呢? webpack 的启动速度慢,热更新速度慢的问题。
webpack 为什么慢:webpack 的运行原理导致的,在使用 webpack 启动项目时,webpack 会根据我们配置文件(webpack.config.js) 中的入口文件(entry),分析出项目项目所有依赖关系,然后打包成一个文件(bundle.js),交给浏览器去加载渲染。
vite 为什么快:利用了 ES module 浏览器遇到内部的 import 引用时,会自动发起 http 请求,去加载对应的模块 的特性,使用 vite 运行项目时,首先会用 esbuild 进行预构建,将所有模块转换为 es module,不需要对我们整个项目进行编译打包,而是在浏览器需要加载某个模块时,拦截浏览器发出的请求,根据请求进行按需编译,然后返回给浏览器。
redux vs zustand
这里对比 redux 的最佳实践 Redux Toolkit 与 zustand。
其实两者都是不错的选择,我从我的角度来讲讲为什么我选择 zustand。
简单易用:Zustand 使用 React 的钩子机制作为状态管理的基础,通过创建自定义 Hook 来提供对状态的访问和更新,与函数式组件和钩子的编程模型紧密配合,使得状态管理变得非常自然和无缝。
轻量级的状态管理库:对比 redux 体积,Redux 的体积相对较大,通常在几十 KB 到 100KB 左右,Zustand 的体积非常小,压缩后不到 1KB。
Zustand 提供了中间件 (middleware) 的概念,允许你通过插件的方式扩展其功能。中间件可以用于处理日志记录、持久化存储、异步操作等需求,使得状态管理更加灵活和可扩展。
Redux Toolkit 是官方推荐的编写 Redux 逻辑的方法。
Zustand 的优点包括:
轻量级,使用起来更简单,适用于中小型应用或者对于快速原型开发。无需繁琐的配置,减少了样板代码,提高了开发效率。 Zustand 的缺点包括:
可能不适用于大型复杂的应用程序,对于更多的状态管理需求可能不够灵活。社区资源和文档相对较少,可能需要更多的自行探索和摸索。
最后再对比一下写法(以持久化存储语言为例):
zustand:
import { create } from 'zustand' |
redux:
import { configureStore, createSlice } from "@reduxjs/toolkit"; |
pnpm vs npm 和 yarn
pnpm 对比 npm 和 yarn 的优势在于:包安装速度快和磁盘空间利用高效。
主要原因:npm/yarn 在不同项目依赖同一个包的情况下,会将这个包安装多次在每个项目中,而 pnpm 安装的包会存储在可寻址的磁盘中,在多个项目同时引用时,只需要用一个硬链接指向该地址就可以使用,大大节约了磁盘空间
pnpm
pnpm 采用硬链接和符号链接到全局磁盘上的内容可寻址存储来管理 node_modules,从而减少磁盘空间使用,同时保持项目的 node_modules 目录整洁。
关于什么是 hard link(硬链接),这里简单说下,在 Linux 文件系统中,磁盘中的文件都有一个索引编号(Inode Index),在 Linux 中,可以多个文件名指向同一索引节点,这种就是硬链接。
硬链接的机制可以让多个不同的位置寻址到相同的空间,也就说硬链接文件和原始文件其实是同一份文件,所以在 pnpm 管理的项目,100 个项目的相同依赖只需占用一份依赖的空间。
而且后续安装依赖时,如果该依赖之前已经安装过了,在 store 中已经有了该依赖,这时候就会直接使用 hard link,大大减少安装时间。
所以,总的来说,pnpm 比起 npm 和 yarn 不仅节省了磁盘空间,并且安装速度更快。
npm
在早期的 npm1 和 npm2 中 node_modules 的目录结构是嵌套的结构,例如有三个包结构,a 包,b 包引用 a 包,c 包引用 b 包,则会出现嵌套结构:
node_modules |
带来的问题:
windows 系统文件路径名限制:嵌套结构非常深的情况下,越深层的依赖的文件路径就越长,这会带来很多麻烦,在 window 系统下,很多程序无法处理超过 260 个字符的文件路径名。
相同的依赖会重复安装造成浪费:比如上面的例子在安装了 C 包后又再安装了其他依赖包(例如叫它 D 包),假如 D 包也引用了测试 B 包,则 B 包会重复安装,并出现在 C 包和 D 包下的 node_modules 中。、
npm 从版本 3 和 yarn 一样开始维护一个扁平化的依赖树,这导致了更少的磁盘空间膨胀,但会导致 node_modules 目录混乱。
node_modules |
yarn
- 使用 yarn.lock 文件解决那时候 npm 安装的不确定性(那时候 npm 还没有 lock 文件,npm5 才有)
- yarn 并行安装的机制比 npm 的顺序安装速度更快,
- 带来了可以从缓存中获取的离线模式。
- 更简洁的命令行输出
- 更好的语义化命令,比如 yarn add/remove 等
文件夹结构
├─ public # 静态资源 |
注意名称规范:文件小写(小驼峰),组件大驼峰,index
CSS 解决方案
- tailwindcss 更高效好用的原子化的 CSS
- CSS Modules 局部作用域 CSS
- Sass/Less CSS 预处理器
- Styled Components CSS in JS
路由方案
- React Router DOM 路由
代码规范
- 命名规范
- 文件组织规范
- css 规范
- js 规范
Git 管理
- GitFlow 分支管理策略
- Commit message 规范