# 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