了解大致目录结构#
只选取了项目的主体部分,细节目录结构全部略去。
YuJudge
├─ config // 项目打包构建(例如webpack)的一些配置
├─ docs // 项目文档
├─ help // 帮助
├─ public // 公共文件
│ ├─ logo // 项目logo, 可以直接修改
├─ scripts // 包的依赖管理文件
├─ src // 源代码
│ ├─ App.tsx // 项目入口
│ ├─ common // 公共文件,例如一些枚举等
│ ├─ components // 公共组件包,独立于页面
│ ├─ config // 全局配置
│ ├─ hooks // 自定义hooks
│ ├─ index.scss // 样式入口
│ ├─ layout // 项目布局
│ │ ├─ cms // cms页面布局
│ │ ├─ common // 常规页面布局
│ ├─ models // 业务模型
│ ├─ network // 网络请求
│ ├─ pages // 页面(组件)
│ │ ├─ cms // 后台管理所有页面
│ │ ├─ common // 所有的一般性页面
│ │ ├─ index.scss // 页面样式出口
│ │ └─ index.tsx // 页面路由出口
│ ├─ router // 全局路由配置
│ ├─ store // 状态管理(暂未使用)
│ ├─ styles // 公共样式
│ └─ utils // 工具相关
当前项目的一些规范#
- 文件夹、文件名统一采用驼峰法命名,特例: 组件名称以大写字母开头。
- 常量全部使用大写字母加下划线的形式。
- 组件/页面的基本目录结构如下所示, 页面分类存放于
page
目录下,组件存放于components
目录下
│ ├─ component // 组件名称
│ │ ├─ childCmp // 依赖的子组件文件夹,一般为该组件特有,如果具有公共性则另起一个组件文件夹
│ │ ├─ component.module.scss // 组件样式
│ │ └─ Component.tsx // 组件名称
项目的路由配置在router
文件夹下, 其中单个路由的配置如下所示。
export interface MenuRouterConfig {
key: string;
path: string;
title: string;
icon?: string;
component?: string;
query?: string;
isAuthRequired?: boolean;
children?: MenuRouterConfig[];
isShowInMenu?: boolean;
}
你只需要将要新增页面的相关信息添加至路由表中(ps.路由表文件名分版块表示,在 router 目录下), 例如:
export const CMS_USERS_MENU: MenuRouterConfig = {
key: "/cms/users",
title: "用户&用户组",
path: "/cms/users",
icon: "UserOutlined",
isShowInMenu: true,
children: [
{
key: "/cms/users/user_manage",
component: "UserManage",
title: "用户管理",
path: "/cms/users/user_manage",
isShowInMenu: true
}
]
};
这表示把UserManage这个页面写入路由表中,隶属于用户/用户组的子路由,你可以通过/cms/users/user_manage
访问之。
最后,不要忘记在页面出口注册一下页面:
import {
DashboardOutlined,
... 省略若干项
} from "@ant-design/icons";
import loadable from "../utils/loadable";
import Common from "../layout/common/Common";
import Solution from "./common/solution/Solution";
... 省略若干项
const Dashboard = loadable(import('./cms/dashboard/Dashboard'));
... 省略若干项
const UserManage = loadable(import('./cms/userManage/UserManage'));
const ProblemHome = loadable(import("./common/problemHome/ProblemHome"));
... 省略若干项
export default {
ProblemManage: ProblemManage,
... 省略若干项
UserManage: UserManage,
} as any;
loadable 包裹的 Import 表示这个页面实行路由懒加载,即在需要的时候进行加载, 加快 app 首次加载速度。
网络请求#
网络请求使用axios, 并对每一个请求进行二次封装,按照请求路径进行文件区分,例如:
export const getJudgeHostsInfo = () => {
return request.get(
"/judge_host/get_judge_hosts_info",
)
}
getJudgeHostsInfo()
.then(() => {
})
.catch(() => {
})
本项目的分页对象如下:
export interface PaginationRequest {
start: number;
count: number;
}
如果有额外的分页请求体,可以继承自本分页对象, 例如:
export interface xxxPaginationRequest extends PaginationRequest {
limit: boolean;
search: string | null;
}
在需要分页请求的页面调用UsePaginationState
const xxxPagination = UsePaginationState<xxxPaginationRequest>(PAGE_BEGIN - 1, 分页请求方法);
UsePaginationState
提供了以下方法,你可以轻松获取它们,无需再处理数据。
xxxPagination.changeCurrentPage()
xxxPagination.items
xxxPagination.paginationInfo
items: [],
count: 0,
page: 0,
total: 0,
totalPage: 0
调试与部署#
项目打包基于webpack,当前分支已经运行了yarn eject
,webpack 配置需要开发者自行管理。
webpack 配置文件位于config/webpack
目录之下。
yarn 脚本文件位于script
目录之下。
安装依赖#
开发环境运行#
生产环境打包#
带外链的生产环境打包#
打开package.json
,修改http://cdn.yuzzl.top为你的外链地址。
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js",
"buildWithPrefix": "node scripts/build.js http://cdn.yuzzl.top",
"upload": "node scripts/upload.js"
}
执行
此时打包出来的所有 js、css 等依赖,均指向你的外链地址而不是build
文件夹的根目录。
集成七牛存储服务#
如果你使用七牛的云存储服务来保存静态文件的话,你可以试试:
打开script/upload.js
, 找到下面内容,按照注释进行修改
const ACCESS_KEY = 'o4fgM7P2lPEyo3已经作废FZ7s_NGdo_xJVNDdKf55apCubX';
const SECRET_KEY = 'YxRkcS8o-GSLMo1已经作废ajWuLjeFxFsMo1WKnOvyrLjB8';
const options = {
scope: "yzlyz已经作废l123",
};
config.zone = uploader.zone.Zone_z2;
带外链打包
执行上传脚本
所有 css、js 等静态文件会被自动上传至七牛服务器,你只需要将index.html、一些图标文件传上服务器进行托管即可。
- 项目无法直接通过双击index.html在浏览器打开,请上传服务器/本地代理运行。
- 如果使用了带外链的生产环境打包,可能是静态文件没有上传成功,可以通过浏览器的开发者工具查看。