react-antd-console 是一个后台管理系统的前端解决方案,封装了后台管理系统必要功能(如登录、鉴权、菜单、面包屑、标签页等),帮助开发人员专注于业务快速开发。项目基于 React 18
、Ant design 5
、Vite
和 TypeScript
等新版本。对于使用到的各项技术,会被持续更新至最新版本。可放心用于生产环境。
为了方便大家更好的掌握和使用本项目,推出系列文章:
如果你喜欢这个项目或认为对你有用,欢迎使用体验和 Star
首先我们需要搞定构建工具问题,我们使用了 Vite 作为构建工具
Vite 是一个超快速的前端构建工具,推动着下一代网络应用的发展
Vite 最大的特点是启动极速(通常 1s 内)、轻量快速的热更新、对 TypeScript 、JSX 、CSS 等支持开箱即用。相较于 Webpack 传统构建工具,其配置极简,并同样可以实现我们想要的诸多功能,维护心智负担极低
如果一个构建工具存在瓶颈,那么哪怕其他有再好的方面,最终也无法选用。所以我们不能忽视 Vite 的缺点。那就是:
Vite 因为减少了源文件( JS/TS/CSS )的工作量,导致并发请求多而拖慢刷新页面的速度。但结合启动和热更新,在速度上,相比 Webpack ,本文档认为仍然具有明显的优势
本项目在开发启动后,刷新首页,共有 168 项请求,耗时 150 至 200 毫秒。作为参考
理论上是有可能的,因为 Vite 开发使用 esbuild, 打包使用 rollup 。但实际情况中,作者从没有碰到过不一致的情况。而且 Vite 即将使用 Rolldown 作为底层打包工具。Rolldown 将保证开发和打包结果完全一致,并提供更快的打包速度。届时可平滑升级
Vite 内置了很多开箱即用的功能,本项目用到的内置功能有:
样式预处理器我们使用的是 Less。在 Vite 中,只需要安装 less 模块即可直接使用
npm i -D less
本项目没有额外配置 less 选项,若需要进一步配置,可参考 Vite 配置 css.preprocessorOptions
对于样式名,不同浏览器可能有不同的前缀,例如 -webkit-
、-ms-
、-moz-
等。但我们写代码时并不想写这些前缀,但打包时可以自动生成。Vite 中如果项目包含有效的 PostCSS 配置 (任何受 postcss-load-config 支持的格式,例如 postcss.config.cjs),它将会自动应用于所有已导入的 CSS 。
安装 PostCSS 插件 autoprefixer
npm i -D autoprefixer
在 <root>/postcss.config.cjs
中配置自动前缀插件即可生效:
// postcss.config.cjs
module.exports = {
plugins: [
require('autoprefixer'),
],
};
参考文档:
<root>/index.html
,可在该 html 中引入入口 ts/tsx 文件src/main.tsx
,在该文件中,初始化了 react 等说明:
<root>/dist
文件夹中也会包含打包后的 html 文件,其源码被引入的 ts/tsx 文件和路径,会被自动转换成打包后的文件和路径打包前:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>react-antd-console</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
打包后:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" type="image/x-icon" href="/images/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>react-antd-console</title>
<script type="module" crossorigin src="/assets/index-B68Xj7Fq.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CHnsXl1V.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
当我们通过 package.json
中的 npm run build:prod
命令打包时,其实是调用了 vite build --mode prod
命令。默认情况下,它使用 <root>/index.html
作为其构建入口点,并生成能够静态部署的应用程序包 <root>/dist/
。若要部署,我们将打完的包放到 nginx 等服务上即可
我们还可以指定打包后的文件所支持的浏览器目标,例如指定为支持 es2015
浏览器
// vite.config.js
export default defineConfig({
build: {
target: 'es2015',
},
})
参考文档:
public 目录 位于根目录的 <root>/public
文件夹。该目录中的资源在开发时能直接通过 / 根路径访问到,并且打包时会被完整复制到目标目录的根目录下
另外有些功能是需要配置的,Vite 配置极其简洁。配置文件位于根目录的 <root>/vite.config.ts
如下:
// vite.config.ts
export default defineConfig({
plugins: [
react(),
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/svg')],
symbolId: 'icon-[dir]-[name]',
}),
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@@': path.resolve(__dirname, './examples'),
},
},
server: {
host: true,
port: 9527,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
esbuild: {
target: 'chrome65',
},
build: {
target: 'es2015',
},
});
以下功能为配置后生效的功能:
// vite.config.js
export default defineConfig({
server: {
host: true,
port: 9527,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
})
/api
开头的 url 时,该请求会被代理到 http://localhost:3000
,并且请求路径会自动去除 /api
启动服务后,Vite 会使用 esbuild 作为编译工具,我们指定下编译的文件所支持的浏览器版本为 chrome65
以上:
// vite.config.js
export default defineConfig({
esbuild: {
target: 'chrome65',
},
})
使用官方的 react 插件 @vitejs/plugin-react,支持:
// vite.config.js
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
})
import
文件时,我们常常会把 <root>/src
别名为 @
,这样编写代码就比较方便
// vite.config.js
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
})
多环境采用 vite
内置的方案。
vite --mode localhost
启动项目时,环境的配置文件,对应的是根目录的 <root>/.env.localhost
文件。.env.localhost
文件中定义的环境变量,可通过 const { VITE_API_HOST } = import.meta.env
在代码中引入。.env.newEnv
文件.env.newEnv
文件中定义环境变量: VITE_SOME_KEY = someValue
src/vite-env.d.ts
定义 VITE_SOME_KEY
的类型ts/tsx
文件中引入环境变量 const { VITE_SOME_KEY } = import.meta.env;
添加构建命令:
// package.json
{
"scripts": {
"build:newEnv": "vite build --mode newEnv",
}
}
执行构建:
npm run build:newEnv
项目总体按最小约束原则约束编码规范,只使用了 eslint
。你可以根据自己的需求自行添加各规范,如 stylelint、prettier 等
[!TIP] 我们认为在编码规范方面,应当在工程统一性和灵活性之间找到一个平衡,而不是一味地使用各种 lint 类工具作强制约束。你可以找到自己团队的平衡点,定制适合自己团队的编码规范
本项目采用官方建议的通用 eslint
规则,如下:
@typescript-eslint/recommended
(eslint
官方赞助的社区 typescript
规则)eslint:recommended
(eslint
官方推荐规则)eslint-plugin-react
(社区流行的 react
规则)详见 <root>/.eslintrc.cjs
eslint 可配合 husky、lint-staged 实现 git commit
时自动校验 eslint
,其他文档和教程很多,在此不再赘述
Light | Dark |
Background Light | Background Dark |
侧分栏 | 侧单栏 |
头分栏 | 头单栏 |
如果你喜欢这个项目或认为对你有用,欢迎使用体验和 Star
1
russ44 38 天前 via Android
cool
|
2
cbythe434 38 天前
腿夹腿撸和手把手撸体验上有差吗
|
3
ZGame 38 天前
挺好看的 学习一下
|
4
michaelluang 38 天前
写得很棒,期待下一篇。
|
8
zhangfg OP @michaelluang 感谢,后面会继续编写
|
10
zclzone 38 天前
写得很好,已 star ,顺便推荐一下 vue-naive-admin ,使用 vue3 + vite ,https://github.com/zclzone/vue-naive-admin
|
12
starcoming 38 天前
支持一下
|
13
zhangfg OP @zclzone 感谢,这个项目 https://github.com/zclzone/vue-naive-admin ,看了也很棒,已 star
|
14
zhangfg OP @starcoming 感谢,欢迎体验使用
|
17
shintendo 37 天前
但实际情况中,作者从没有碰到过不一致的情况
------ 有一个挺常见的坑,开发和打包后的 CSS 顺序不一致,相关 issue 开了 4 年了至今未解决 |
18
Ma4cus 37 天前
厉害了,有 vue 的吗
|
19
ColdBird 37 天前
还好不是手把腿
|
23
HHAO2019 37 天前
好奇问一下, 多标签页怎么实现的 antd 好像默认不支持
|
24
zclzone 37 天前
代码运行跟你预览地址的不一样,是有代码还没提交吗
|
25
randomstream 37 天前
|
26
344457769 37 天前
|
27
zhangfg OP @HHAO2019 antd 有 Tabs 组件。传 items 就会展示多标签,传 activeKey 会高亮指定的 tab 。所以只需要管理好 items 数据即可。items 相关数据存到 localstorage,刷新页面就还会继续展示。另外封装好拖拽和右键逻辑以复用,我们就可以只写样式,便可产出多个不同样式的标签页。
|
28
zhangfg OP @zclzone 是的。目前是一个相对比较干净的模板,只包含必要的功能,在这个基础上做二开,是比较方便的。功能越多,二开就越麻烦,尤其是主题那块。后续我再写写后面的系列文章,根据大家使用的情况补功能进来(如果大家还感兴趣的话)
|
29
zhangfg OP @randomstream 都没用 8964
|
30
randomstream 37 天前
@zhangfg #29 好家伙,搜了才知道,🐮
|
31
1622346252 37 天前
先 start 后看
|
32
bao3 37 天前
广大女性心头一紧。
|
33
yaroga 37 天前
学习下,不用 monorepo 么
|
34
zhangfg OP @1622346252 老哥,谢谢你,你是好人
|
37
Vitumoc 37 天前
还是你们前端圈子奔放,上一个还是手摸手呢=。=
到这就腿夹腿了 以后的我都不敢想 |
38
Vitumoc 37 天前
看了一下,爽,打算把我之前 vue2 + element 的老后台改过来了
|
41
godymho 37 天前
你这个动态多标签是基于什么的呀
|
43
zclzone 37 天前
@zhangfg 预览版本的很多功能都没有,如果是想保持干净的模板可以提供多个版本的,让用户去选择使用哪个,很多这类开源项目都是这样做的。预览是完整版,开源的是阉割版,多少有点挂羊头卖狗肉的嫌疑,当然,你可能有别的想法或者顾虑,开源的东西不能要求太多,我仅仅只是建议
|
44
yurenfeijing 37 天前
挺好的,已经 star 了,另外 github 代码是不是最新的啊,怎么找不到主题和 debugger.html 那块的代码?
|
45
zhangfg OP @zclzone 谢谢你的建议。所谓的阉割版是一个干净的模板,它是通用的。所谓的完整版,是在模板的基础上丰富的,它还未完全准备好,还没准备完全开源。如果哪些功能有必要并且是通用的,会根据大家使用的情况按需加到模板里。所谓的“完整版”,是我个人的完整版,不是所有人的完整版。我会把这个情况在 github 里说明下,或许会再开一个链接,两个预览链接都放着。(无论如何,我不太喜欢阉割版这个说法,我们可以多讨论技术问题本身)
|
46
zhangfg OP @yurenfeijing 那您可千万别 star 啊
|
49
zhangfg OP @godymho 上面有回复类似问题:antd 有 Tabs 组件。传 items 就会展示多标签,传 activeKey 会高亮指定的 tab 。所以只需要管理好 items 数据即可。items 相关数据存到 localstorage,刷新页面就还会继续展示。另外封装好拖拽和右键逻辑以复用,我们就可以只写样式,便可产出多个不同样式的标签页。
再补充一些,如何管理 items 数据:当点击标签,需要跳转路由;当路由切换,需要新增 item ;当点击关闭标签,需要删除当前 item 并需要跳转到下一个 item ;右键菜单还有一些关闭其他,关闭右侧,关闭左侧的逻辑,和上述关闭逻辑是类似的。把这些逻辑封装封装。 |
51
yurenfeijing 37 天前
@zhangfg 这有啥,那就取消呗😅谁能想到放的截图是完整的,代码是阉割的,也只有一个分支,我有疑问不是很正常吗?
|
52
zhangfg OP @yurenfeijing 好嘞
|
53
zhangfg OP 更新:
[在线预览]( https://template.react-antd-console.site) | [个人 pro 版在线预览]( https://react-antd-console.site) | [文档]( https://doc.react-antd-console.site) |
54
jones2000 36 天前
Vite 很不好用, 每次改 node_modules 里面插件得源码, 都不会自动编译, 还要删 vite 得缓存, 然后在重新编译, 麻烦得要死。
|
55
zhangfg OP @jones2000 一般不会改 node_modules 里的源码吧...或许应该提 issue 或 fork 或 monorepo 或私仓
|
57
jones2000 36 天前
@zhangfg 发”issue“要等到什么时候。 公司都是内网,不能访问外网。 一次性把包下完,移到内网。不满足需求得, 直接手动 node_modules 里面改。
|
59
hutoer 36 天前
OP ,开源版,内容会不少了些?你看看 https://www.v2ex.com/t/1039863 这位和你用的技术栈很像
|
61
jones2000 35 天前
@zhangfg 编译出来的东西, 跟 node_modules 里面的源码对不上。 编译的时候根本就不会去检测 node_modules 源码里面哪些插件源码否变动了,就简单的判断了下插件的版本号。这个就是所谓的“更快的打包速度”。
|
62
zhangfg OP 大家好,收到一些反馈后,react-antd-console 升级了以下功能:
新增功能: - 动态路由示例 - 动态 meta 示例 - 外链示例 - 单 sider 示例 - 无 layout 示例 - 路由权限示例 - 局部权限示例 - 全屏 优化: - 整体布局样式 - 首页样式 修复: - 非动态参数路由使用 router.setSiblings 无效的问题 另外说明下,有个别评论认为 react-antd-console 是一个阉割版,其实这是一个误解。它是一个模板,另外的 pro 版是本项目的一个拓展。它们的核心代码全都是一模一样的,只是少了示例代码,少了主题功能。这些功能,我认为对于真正要使用 react-antd-console 开发的人来说,示例代码是冗余的,而主题是因人而异的。为了消除可能的误解,现在增加了一些示例代码,如果不需要,可以删除掉。最后,react-antd-console 是一个诚意满满的开源项目,再次欢迎大家使用体验,希望对你能有用。如果喜欢,请 star 一下,谢谢大家! 在线预览: https://template.react-antd-console.site github 地址: https://github.com/diandian18/react-antd-console |