@jikeytang
2023-02-03T01:27:09.000000Z
字数 7007
阅读 834
2023-blog
随着 http://www.react-admin.cn 的上线,今天总结一下这个项目的点点滴滴。这项目有几个模块组成,分别是
Dumi: 提供静态文档的生成支持,满足Markdown格式转化为html并串联成一个网站的需求。
仓库地址 https://gitee.com/jikey/react-admin-cn
技术栈为:Dumi,
Next:满足SEO前提下动态页面实现
仓库地址 https://gitee.com/jikey/react-admin-cn
技术栈为:Next, Antd, Ahooks, Bytemd, Tailwindcss
Vue3: 后台管理
仓库地址 https://gitee.com/jsfront/vue3-tiger-admin
技术栈为:Vue3, Arce, VueUse, UnoCSS,
Nestjs: 提供基础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中创建模块即可。
Dumi 近期发布2.x版本,初步评估还是满足简单Markdown转换为文档平台的需求。
对Node版本有特殊要求,最低支持 Node.js v14 版本,因为在Pnpm中为了平衡Nest,最后运行版本为Node 16.0.0
上线提前,基础配置约定好,减免后期踩坑的风险。比如Dumi要部署到二级目录http://react-admin.cn/doc,那除了配置base之外还要配置publicPath。
export default defineConfig({base: BaseUrl,publicPath: BaseUrl, // 打包文件时,引入地址生成 publicPath/xxx.js});
打包
$ cd react-admin-cn\apps\md$ pnpm build
然后上传 react-admin-cn\apps\md\dist目录中的文件到wwwroot/domain/doc目录即可。
Next要求Node最低版本为Node.js 14.6.0,
Nextjs 近期发了13,增加了快如闪电的Turbopack,在命令行手工开启,next dev --turbo,为了项目快速开发,此项目暂时没有开启。其它新特性:NextJS 13发布,包含大量新特性。
有几个插件用的还是比较方便的:
next-progress
页面顶部进度条,需要放到Suspense中。
@carbon/icons-react
Icons的扩展方案,使用起来也非常的方便
import { OverflowMenuHorizontal } from '@carbon/icons-react'<OverflowMenuHorizontal />
@nextui-org/react
antd 的备份方案,4.x antd的翻页组件有bug,暂时用nextui来代替。
// 疯狂点击只响应最后一次const onSearch = debounce(() => {onEmit()}, 500)
Tailwindcss
本来我迷恋于Unocss的灵活和速度,可惜在Nextjs中热更新容易失去响应,只能换回Tailwindcss,虽然Unocss也提供了一个Nextjs下的案例。
@bytemd/react
bytemd是字节开发的一款富文本编辑器,可用于vue,react,主题可以使用juejin-markdown-themes,虽然名叫juejin,其它里边有很多风格的css选择,具体在这个 node_modules\juejin-markdown-themes\dist 目录下。
qrcode.react
其中一个页面需要分享展示用到二维码,用的这款,按照文档使用起来也没有大的问题。
react-copy-to-clipboard
按钮复制用这款,也没有什么大的问题。
react-infinite-scroll-component
滚动加载用到了这款,出现的问题是出现滚动条,添加样式强制显示即可隐藏滚动条。
<InfiniteScrollstyle={{ overflow: 'visible' }}hasMore={hasMore}loader={(<div className="text-center mt-5"><Spin indicator={antIcon} /></div>)}>text</InfiniteScroll>
| 技术 | 说明 | 官网 |
|---|---|---|
| Nextjs | React应用开发框架 | https://nextjs.org/ |
| Mobx | 全局状态管理模式 | https://mobx.js.org/ |
| Mobx-react-lite | mobx-react的轻量化版本 | https://github.com/mobxjs/mobx-react-lite |
| Axios | HTTP 库 | https://github.com/axios/axios |
| Ant-design | UI组件库 | https://ant-design.gitee.io/ |
| Nextui | UI组件库 | https://nextui.org/ |
| Ahooks | React Hooks 库 | https://ahooks.js.org/ |
| Bytemd | Markdown编辑器 | https://github.com/bytedance/bytemd |
| Tinymce | 富文本编辑器 | https://www.tiny.cloud/ |
| Dayjs | JavaScript 日期处理类库 | https://day.js.org/zh-CN/ |
| SCSS | CSS预处理器 | https://sass-lang.com/ |
| Carbon | 图标字体库 | https://carbondesignsystem.com/guidelines/icons/library/ |
| Qrcode | 二维码 | 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 |
| Tailwindcss | 原子CSS库 | https://tailwindcss.com/docs/guides/nextjs |
| Juejin-markdown-themes | 掘金 Markdown 主题 | https://github.com/xitu/juejin-markdown-themes |
| Typescript | 类型约束 | https://www.typescriptlang.org/ |
| 系统 | 工具 | 官网 |
|---|---|---|
| Vscode | 开发工具 | https://code.visualstudio.com/ |
| Navicat | 数据库管理工具 | https://www.navicat.com.cn/ |
| Atom | 源码阅读工具 | https://atom.io/ |
| Cmder | Cmd替代工具[windows] | https://cmder.net/ |
| Notepad3 | 临时单文件编辑[windows] | https://www.rizonesoft.com/downloads/notepad3/ |
| Chrome | 调试工具 | https://www.google.com/intl/zh-CN/chrome/ |
├─.next // 开发目录├─.out // 发布目录├─api // 请求文件├─components // 公共组件├─config // 配置├─context├─hooks├─layouts // 布局文件├─pages // 页面├─public // 静态资源├─styles // 所有 Scss 文件└─utils // 工具文件
根目录下运行 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.0nvm use 16.0.0// 安装依赖npm install// 启动项目npm start// 清除 node_modulesnpm run clean// 全局安装 rimraf 之后方可使用npm i rimraf -g// 清除 node_modules 重新安装依赖// 等同于 npm run clean && npm installnpm run reinstall
需要注意的是:Nextjs的开发运行目录和打包上线目录默认都是.next,所以,打包输出结果要仔细看,要不然会把开发时的文件误上传。解决办法就是修改打包后输出目录:
// next.config.jsmodule.exports = {distDir: '.out',}// .gitignore# next.js/.next//out//.out/
首先在nginx增加配置,转发nextjs的启动端口。
Nextjs虽然支持basePath进行二级目录的部署,可惜一刷新又出现basePath路径找不到的情况,只能在根目录部署。
location / {proxy_pass http://127.0.0.1:3600/;proxy_http_version 1.1;proxy_set_header Host $host;}
根目录新建ecosystem.config.js,然后用pm2启动这个文件就可以了。
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日志进行排错。
url-loader也不能解决,解决办法,转换为Base64图片。/,然后打包后还是路径丢失
import Image from 'next/image'import Logo from '@/public/images/logo.png'
/.next/static下,可以手工修改也可以是Git commit id。
generateBuildId: async () => 'v1',
images: {domains: ['react-admin.cn'],},
package.json到根目录然后在服务端全量安装node_modules
$ 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
TypeError: Cannot read properties of undefined (reading 'context')
然后设置为false就没事了。
swc全称是Speedy Web Compiler,基于Rust语言的JS编译器,主要对标Babel,准备代替Babel。
基础的工程采用Pnpm Monorepo的方式来搭建,在满足基础开发的需求上能够灵活扩展模块,并保持代码解耦。这方面的其它介绍:
由于整体是React的相关技术栈,计划帮助文档部分由dumi来实现,可以快速的将基础的Markdown快速转化为页面,入口地址由Nginx来安排。
约定式路由式的开发,即 pages目录下所有文件夹层级为路由访问路径。比如 pages/admin/index.tsx,那访问的路径就是https://react-admin.cn/admin。
pages中除了路由文件之外不建议放其它文件,要放其它扩展名文件还需要在next.config.js中增加配置。
module.exports = {pageExtensions: ['mdx', 'jsx', 'js', 'ts', 'tsx']}
基础的布局由Layouts负责,共有这几个:
Nextjs 共有两种渲染模式,这两个模式下有两种获取数据的方式
getStaticProps 静态模式下使用,在构建时会调用该函数获取数据并返回到 props,会在构建时渲染生成 htmlgetStaticProps 中的 context 参数包含了常用的请求的 params,preview,previewData,locale 等参数服务器端渲染模式,即每次请求时在服务器端重新生成 html。
getServerSideProps 服务器端渲染模式下使用,会在每次请求时先获取数据,接着重新生成 html 后再将页面返回到客户端。getServerSideProps 中的 context 参数包含了常用的请求的 req、res、params、query 等参数axios
页面上在useEffect中异步获取数据,这块的代码在浏览器端运行。
通过 next/head 组件增加页面的meta 的 keywords, description 标签。
Next.js 12
<title>首页 - {title}</title>
Next.js 13
`<title>{`首页 - ${title}`}</title>`
Next.js 12
<Link href=""><a target="_blank" rel="noreferrer">{title}</a></Link>
Next.js 13
<Link href="" target="_blank" rel="noreferrer">{title}</Link>
用这个命令全局替换,然后全局校验Eslint
$ npx @next/codemod new-link .
如果还想找回此文,您可以点右上角 💖Star 💖 收藏 + 支持
还可以加Q群进行反馈交流: