# react-admin-cn
**Repository Path**: confused-king0/react-admin-cn
## Basic Information
- **Project Name**: react-admin-cn
- **Description**: react-admin.cn 基于nextjs, ant, ahooks, axios, bytemd, scss 的管理模板集中地
- **Primary Language**: JavaScript
- **License**: MIT
- **Default Branch**: master
- **Homepage**: http://react-admin.cn
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 3
- **Created**: 2023-11-03
- **Last Updated**: 2023-11-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
随着 [http://www.react-admin.cn](http://www.react-admin.cn) 的上线,今天总结一下这个项目的点点滴滴。这项目有几个模块组成,分别是
- Dumi: 提供静态文档的生成支持,满足`Markdown`格式转化为`html`并串联成一个网站的需求。
仓库地址 [https://gitee.com/jikey/react-admin-cn](https://gitee.com/jikey/react-admin-cn)
技术栈为:Dumi,
- Next:满足`SEO`前提下动态页面实现
仓库地址 [https://gitee.com/jikey/react-admin-cn](https://gitee.com/jikey/react-admin-cn)
技术栈为:Next, Antd, Ahooks, Bytemd, Tailwindcss
- Vue3: 后台管理
仓库地址 [https://gitee.com/jsfront/vue3-tiger-admin](https://gitee.com/jsfront/vue3-tiger-admin)
技术栈为:Vue3, Arce, VueUse, UnoCSS,
- Nestjs: 提供基础`API`数据源
仓库地址 [https://gitee.com/jsfront/nest-admin-api](https://gitee.com/jsfront/nest-admin-api)
技术栈为:Nestjs, Mysql, Typeorm,
先从全局角度总结一下:
- 定位
最原始的出发点是为`react`开发者提供一个以管理模板为核心,其它资源为辅助的信息知识类平台。能匹配管理模板及周边几个关键字相关的内容整合到一起,方便筛选查找。
- 目标用户
与`React`相关的开发者
- 技术选型
react 首选`next`,后端其实首推`go`,奈何此项目周边以前端为主的群体比较多,所以选择`nest`,备选`koa2`,数据库为`mysql`
- 代码组织
采用的是Pnpm Monorepo, Monorepo 是把多个工程放到一个 `git` 仓库中进行管理,共享,复用代码等的工具。 开发时模块相互引用,发布时模块独立打包。这样代码能复用,发布又灵活,方便后续的扩展。比如后续要加个`Admin`平台,直接在apps中创建模块即可。
### 1. Dumi
#### 1.1 基本介绍
[Dumi](https://d.umijs.org/guide) 近期发布2.x版本,初步评估还是满足简单`Markdown`转换为文档平台的需求。
对`Node`版本有特殊要求,最低支持 Node.js v14 版本,因为在Pnpm中为了平衡`Nest`,最后运行版本为`Node 16.0.0`
#### 1.2 如何发布上线
上线提前,基础配置约定好,减免后期踩坑的风险。比如`Dumi`要部署到二级目录`http://react-admin.cn/doc`,那除了配置`base`之外还要配置`publicPath`。
```
export default defineConfig({
base: BaseUrl,
publicPath: BaseUrl, // 打包文件时,引入地址生成 publicPath/xxx.js
});
```
打包
```javascript
$ cd react-admin-cn\apps\md
$ pnpm build
```
然后上传 `react-admin-cn\apps\md\dist`目录中的文件到`wwwroot/domain/doc`目录即可。
### 2. Next介绍
`Next`要求`Node`[最低版本](https://nextjs.org/docs/getting-started)为`Node.js 14.6.0`,
#### 2.1 基本介绍
Nextjs 近期发了13,增加了快如闪电的`Turbopack`,在命令行手工开启,`next dev --turbo`,为了项目快速开发,此项目暂时没有开启。其它新特性:[NextJS 13发布,包含大量新特性](https://secstep.com/next-js-13-published/)。
有几个插件用的还是比较方便的:
- [next-progress](https://github.com/beeinger/next-progress)
页面顶部进度条,需要放到Suspense中。
- [@carbon/icons-react](https://carbondesignsystem.com/guidelines/icons/library/)
Icons的扩展方案,使用起来也非常的方便
```
import { OverflowMenuHorizontal } from '@carbon/icons-react'
```
- [@nextui-org/react](https://nextui.org/)
antd 的备份方案,4.x antd的翻页组件有bug,暂时用nextui来代替。
- [lodash](https://lodash.com/)
只用了debounce,也可以使用[lodash-es](https://www.npmjs.com/package/lodash-es)版本,偶尔打包时会报错,所以选择稳定版本。
```javascript
// 疯狂点击只响应最后一次
const onSearch = debounce(() => {
onEmit()
}, 500)
```
- [Tailwindcss](https://tailwindcss.com/docs/guides/nextjs)
本来我迷恋于`Unocss`的灵活和速度,可惜在`Nextjs`中热更新容易失去响应,只能换回`Tailwindcss`,虽然`Unocss`也提供了一个`Nextjs`下的[案例](https://github.com/unocss/unocss/blob/main/examples/next/next.config.js)。
- [@bytemd/react](https://github.com/bytedance/bytemd)
bytemd是字节开发的一款富文本编辑器,可用于vue,react,主题可以使用[juejin-markdown-themes](juejin-markdown-themes),虽然名叫juejin,其它里边有很多风格的css选择,具体在这个 `node_modules\juejin-markdown-themes\dist` 目录下。
- [qrcode.react](https://github.com/zpao/qrcode.react)
其中一个页面需要分享展示用到二维码,用的这款,按照文档使用起来也没有大的问题。
- [react-copy-to-clipboard](https://github.com/nkbt/react-copy-to-clipboard)
按钮复制用这款,也没有什么大的问题。
- [react-infinite-scroll-component](https://github.com/ankeetmaini/react-infinite-scroll-component)
滚动加载用到了这款,出现的问题是出现滚动条,添加样式强制显示即可隐藏滚动条。
```
)}
>text
```
#### 2.3 技术栈
技术 | 说明 | 官网
----|----|----
Nextjs | React应用开发框架 | [https://nextjs.org/](https://nextjs.org/)
Mobx | 全局状态管理模式 | [https://mobx.js.org/](https://mobx.js.org/)
Mobx-react-lite | mobx-react的轻量化版本 | [https://github.com/mobxjs/mobx-react-lite](https://github.com/mobxjs/mobx-react-lite)
Axios | HTTP 库 | [https://github.com/axios/axios](https://github.com/axios/axios)
Ant-design | UI组件库 | [https://ant-design.gitee.io/](https://ant-design.gitee.io/)
Nextui | UI组件库 | [https://nextui.org/](https://nextui.org/)
Ahooks | React Hooks 库 | [https://ahooks.js.org/](https://ahooks.js.org/)
Bytemd | Markdown编辑器 | [https://github.com/bytedance/bytemd](https://github.com/bytedance/bytemd)
Tinymce | 富文本编辑器 | [https://www.tiny.cloud/](https://www.tiny.cloud/)
Dayjs | JavaScript 日期处理类库 | [https://day.js.org/zh-CN/](https://day.js.org/zh-CN/)
SCSS | CSS预处理器 | [https://sass-lang.com/](https://sass-lang.com/)
Carbon | 图标字体库 | [https://carbondesignsystem.com/guidelines/icons/library/](https://carbondesignsystem.com/guidelines/icons/library/)
Qrcode | 二维码 | [https://github.com/zpao/qrcode.react](https://github.com/zpao/qrcode.react)
React-copy-to-clipboard | 复制 | [https://github.com/nkbt/react-copy-to-clipboard](https://github.com/nkbt/react-copy-to-clipboard)
React-infinite-scroll-component | 滚动加载 | [https://github.com/ankeetmaini/react-infinite-scroll-component](https://github.com/ankeetmaini/react-infinite-scroll-component)
Tailwindcss | 原子CSS库 | [https://tailwindcss.com/docs/guides/nextjs](https://tailwindcss.com/docs/guides/nextjs)
Juejin-markdown-themes | 掘金 Markdown 主题 | [https://github.com/xitu/juejin-markdown-themes](https://github.com/xitu/juejin-markdown-themes)
Typescript | 类型约束 | [https://www.typescriptlang.org/](https://www.typescriptlang.org/)
#### 2.3 开发工具
系统 | 工具 | 官网
----|----|----
Vscode | 开发工具 | [https://code.visualstudio.com/](https://code.visualstudio.com/)
Navicat | 数据库管理工具 | [https://www.navicat.com.cn/](https://www.navicat.com.cn/)
Atom | 源码阅读工具 | [https://atom.io/](https://atom.io/)
Cmder | Cmd替代工具[windows] | [https://cmder.net/](https://cmder.net/)
Notepad3 | 临时单文件编辑[windows] | [https://www.rizonesoft.com/downloads/notepad3/](https://www.rizonesoft.com/downloads/notepad3/)
Chrome | 调试工具 | [https://www.google.com/intl/zh-CN/chrome/](https://www.google.com/intl/zh-CN/chrome/)
#### 2.4 文件结构
```
├─.next // 开发目录
├─.out // 发布目录
├─api // 请求文件
├─components // 公共组件
├─config // 配置
├─context
├─hooks
├─layouts // 布局文件
├─pages // 页面
├─public // 静态资源
├─styles // 所有 Scss 文件
└─utils // 工具文件
```
#### 2.5 如何在本地运行
根目录下运行 `pnpm install`,然后运行 `pnpm dev`,最后执行的是:
```
pnpm --stream -r dev
```
也可以只启动子应用,进入子目录下运行`pnpm dev`。比如:
```
$ cd react-admin-cn\apps\md
$ pnpm dev
$ cd react-admin-cn\apps\ssr
$ pnpm dev
```
其它Node版本信息
```
// 切换环境
nvm install 16.0.0
nvm use 16.0.0
// 安装依赖
npm install
// 启动项目
npm start
// 清除 node_modules
npm run clean
// 全局安装 rimraf 之后方可使用
npm i rimraf -g
// 清除 node_modules 重新安装依赖
// 等同于 npm run clean && npm install
npm run reinstall
```
#### 2.6 如何发布上线
需要注意的是:`Nextjs`的开发运行目录和打包上线目录默认都是`.next`,所以,打包输出结果要仔细看,要不然会把开发时的文件误上传。解决办法就是修改打包后输出目录:
```
// next.config.js
module.exports = {
distDir: '.out',
}
// .gitignore
# next.js
/.next/
/out/
/.out/
```
##### 2.6.1 Nginx配置
首先在nginx增加配置,转发`nextjs`的启动端口。
`Nextjs`虽然支持`basePath`进行二级目录的部署,可惜一刷新又出现`basePath`路径找不到的情况,只能在根目录部署。
```javascript
location / {
proxy_pass http://127.0.0.1:3600/;
proxy_http_version 1.1;
proxy_set_header Host $host;
}
```
##### 2.6.2 启动Nextjs
根目录新建`ecosystem.config.js`,然后用pm2启动这个文件就可以了。
```javascript
module.exports = {
apps: [{
name: 'react-admin-ssr',
script: 'npm',
args: 'start',
cwd: '/www/wwwroot/react-admin.cn',
autorestart: true,
watch: true,
// 不用监听的文件
ignore_watch: [
'node_modules',
'logs'
],
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production',
BASE_PATH: "",
PORT: 3006
}
}]
}
```
然后根据域名访问,如果出现500,说明后端相关有问题,查看`Nginx, Pm2`日志进行排错。
##### 2.6.3 发布问题
- Favicon 图片不能拷贝到发布目录
就算安装`url-loader`也不能解决,解决办法,转换为Base64图片。
- 图片路径
文档讲可以用 `/`,然后打包后还是路径丢失
```javascript
import Image from 'next/image'
import Logo from '@/public/images/logo.png'
```
- [手工调整buildid](https://nextjs.org/docs/api-reference/next.config.js/configuring-the-build-id)
Nextjs前台静态资源会识别版本信息,最终影响生成目录路径在 `/.next/static`下,可以手工修改也可以是`Git commit id`。
```javascript
generateBuildId: async () => 'v1',
```
- image
images中添加允许域名
```javascript
images: {
domains: ['react-admin.cn'],
},
```
- package.json
需要上传`package.json`到根目录然后在服务端全量安装`node_modules`
- Nginx 缓存
在其它机型上没有碰到这个问题,只有在腾讯云上碰到这个问题,代理转发有缓存,需要清目录后杀掉进程后启动nginx
```
$ cd /www/server/nginx/proxy_cache_dir // nginx缓存目录
$ pkill nginx // 强制关闭
$ /etc/init.d/nginx start // 启动
$ /etc/init.d/nginx stop
$ /etc/init.d/nginx restart
```
- swcMinify 设置
[swcMinify 13之后就默认为true了](https://nextjs.org/docs/upgrading#v13-summary),然后Bytemd打包发布就报错了,
```
TypeError: Cannot read properties of undefined (reading 'context')
```
然后设置为false就没事了。
[swc](https://swc.rs/)全称是`Speedy Web Compiler`,基于Rust语言的JS编译器,主要对标Babel,准备代替Babel。
### 3. 开发介绍
#### 3.1 基本介绍
- 基础的工程采用`Pnpm Monorepo`的方式来搭建,在满足基础开发的需求上能够灵活扩展模块,并保持代码解耦。这方面的其它介绍:
- [Laffery - 基于pnpm搭建monorepo项目](https://juejin.cn/post/7084582387060834340)
- [BestAns - pnpm + workspace + changesets 构建你的 monorepo 工程](https://juejin.cn/post/7098609682519949325)
- 由于整体是`React`的相关技术栈,计划帮助文档部分由[dumi](https://d.umijs.org/)来实现,可以快速的将基础的[Markdown](https://markdown.com.cn/intro.html)快速转化为页面,入口地址由[Nginx](https://www.digitalocean.com/community/tools/nginx?global.app.lang=zhCN)来安排。
#### 3.2 约定式路由
约定式路由式的开发,即 `pages`目录下所有文件夹层级为路由访问路径。比如 `pages/admin/index.tsx`,那访问的路径就是`https://react-admin.cn/admin`。
`pages`中除了路由文件之外不建议放其它文件,要放其它扩展名文件还需要在`next.config.js`中增加[配置](https://nextjs.org/docs/api-reference/next.config.js/custom-page-extensions)。
```javascript
module.exports = {
pageExtensions: ['mdx', 'jsx', 'js', 'ts', 'tsx']
}
```
#### 3.3 基础布局
基础的布局由`Layouts`负责,共有这几个:
- default
负责基础页面的上中下式布局
- custom
备选
#### 3.4 获取数据
`Nextjs` 共有两种渲染模式,这两个模式下有两种获取数据的方式
- 静态模式(默认),即在构建时生成 html,并每次请求时复用
- `getStaticProps` 静态模式下使用,在构建时会调用该函数获取数据并返回到 props,会在构建时渲染生成 html
- `getStaticProps` 中的 context 参数包含了常用的请求的 params,preview,previewData,locale 等参数
- 服务器端渲染模式,即每次请求时在服务器端重新生成 html。
- `getServerSideProps` 服务器端渲染模式下使用,会在每次请求时先获取数据,接着重新生成 html 后再将页面返回到客户端。
- `getServerSideProps` 中的 context 参数包含了常用的请求的 req、res、params、query 等参数
- axios
页面上在`useEffect`中异步获取数据,这块的代码在浏览器端运行。
#### 3.5 SEO增强
通过 `next/head` 组件增加页面的`meta` 的 `keywords, description` 标签。
#### 3.6 更新到Next.js 13
- Title变化
Next.js 12
```html
首页 - {title}
```
Next.js 13
```html
`{`首页 - ${title}`}`
```
- Link的变化
Next.js 12
```html
{title}
```
Next.js 13
```html
{title}
```
[用这个命令全局替换](https://stackoverflow.com/questions/71422463/how-to-fix-unexpected-behavior-of-next-link-when-it-is-a-child-of-a-button),然后全局校验`Eslint`
```
$ npx @next/codemod new-link .
```
如果还想找回此文,您可以点右上角 💖Star 💖 收藏 + 支持
还可以加Q群进行反馈交流:
- Node交流群 422910907
- React交流群 530415177
- Javascript交流群 492107297