@jikeytang
2023-02-03T09:27:09.000000Z
字数 7007
阅读 546
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
滚动加载用到了这款,出现的问题是出现滚动条,添加样式强制显示即可隐藏滚动条。
<InfiniteScroll
style={{ 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.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
需要注意的是:Nextjs
的开发运行目录和打包上线目录默认都是.next
,所以,打包输出结果要仔细看,要不然会把开发时的文件误上传。解决办法就是修改打包后输出目录:
// next.config.js
module.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群进行反馈交流: