|
|
1 Minggu lalu | |
|---|---|---|
| .cursor | 1 bulan lalu | |
| .vscode | 2 bulan lalu | |
| build | 1 Minggu lalu | |
| public | 2 bulan lalu | |
| src | 1 Minggu lalu | |
| types | 1 Minggu lalu | |
| .env | 2 bulan lalu | |
| .env.development | 2 bulan lalu | |
| .env.localdev | 2 bulan lalu | |
| .env.production | 2 bulan lalu | |
| .env.test | 2 bulan lalu | |
| .gitignore | 1 Minggu lalu | |
| .markdownlint.json | 2 bulan lalu | |
| .npmrc | 2 bulan lalu | |
| .nvmrc | 2 minggu lalu | |
| .prettierrc | 2 bulan lalu | |
| .stylelintrc.mjs | 2 bulan lalu | |
| README.md | 1 Minggu lalu | |
| commit.sh | 1 bulan lalu | |
| commitlint.config.js | 2 bulan lalu | |
| common.sh | 1 bulan lalu | |
| eslint.config.js | 2 bulan lalu | |
| index.html | 2 bulan lalu | |
| package.json | 1 Minggu lalu | |
| pnpm-lock.yaml | 1 Minggu lalu | |
| pnpm-workspace.yaml | 1 Minggu lalu | |
| postcss.config.js | 2 bulan lalu | |
| pull.sh | 1 bulan lalu | |
| push.sh | 1 bulan lalu | |
| react-router.config.ts | 1 Minggu lalu | |
| sync.sh | 1 bulan lalu | |
| tailwind.config.js | 2 bulan lalu | |
| tsconfig.json | 1 Minggu lalu | |
| vite.config.ts | 1 Minggu lalu |
基于 React + TypeScript + Vite 的 H5 前端项目。
依赖统一用 pnpm 命令管理(
pnpm add/pnpm add -D),勿手改 package.json 版本号,否则会与 lockfile 不一致导致frozen-lockfile安装失败。
pnpm install --frozen-lockfile
pnpm dev
浏览器访问控制台输出的本地地址即可。
项目支持两种渲染模式,同一份代码、构建时切换(互斥,一次只出一种产物)。两种模式与 --mode(环境:localdev/development/test/production)正交,通过不同的 npm script 选择(脚本内部用 APP_RENDER_MODE 环境变量传给 vite.config.ts)。
| 模式 | 入口 | 路由 | i18n | 产物 | 适用 |
|---|---|---|---|---|---|
| SSG(默认) | root.tsx / entry.client.tsx |
/:lang/home(路径前缀多语言) |
frameworkI18n.ts(同步 init) |
dist/client/(预渲染静态 HTML) |
需爬虫/SEO 可见内容,官网/落地页 |
| CSR | index.html / main.tsx |
/home(无语言前缀) |
i18n/index.ts(LanguageDetector 异步) |
dist/(空壳 SPA) |
纯单页应用,无预渲染需求 |
两套入口、路由(
src/routes.tsvssrc/router/)、i18n 并存且完全独立,由APP_RENDER_MODE决定实际加载哪套。详见 SSG 架构文档。
| 命令 | 说明 |
|---|---|
pnpm dev |
本地开发(默认 = dev:ssg) |
pnpm dev:ssg / pnpm dev:csr |
指定模式本地开发(.env.localdev) |
pnpm build |
生产构建(默认 = build:ssg:prod) |
pnpm build:ssg:{dev,test,prod} |
SSG 模式各环境构建 → dist/client/ |
pnpm build:csr:{dev,test,prod} |
CSR 模式各环境构建(先 tsc,再 vite build) → dist/ |
pnpm build:dev / build:test / build:prod |
默认模式(SSG)各环境构建别名 |
pnpm typecheck |
生成路由类型并做 TS 类型检查(react-router typegen && tsc) |
pnpm preview |
预览 SSG 产物(= preview:ssg) |
pnpm preview:ssg |
用 sirv 静态伺服 dist/client/(端口 8848) |
pnpm preview:csr |
用 sirv 静态伺服 dist/(端口 8848) |
pnpm lint / pnpm lint:fix |
ESLint 检查 / 自动修复 |
pnpm stylelint / pnpm stylelint:fix |
样式检查 / 自动修复 |
通过不同 .env 文件区分环境,Vite 按 mode 加载:
| 文件 | 何时加载 |
|---|---|
.env |
始终加载(公共默认) |
.env.localdev |
pnpm dev(--mode localdev) |
.env.development |
pnpm build:dev |
.env.production |
pnpm build / pnpm build:prod |
.env.test |
pnpm build:test |
.env.local |
本地覆盖,除 test 外都会加载(一般不提交) |
需在环境文件中配置的变量见 .env 内注释或项目文档。
/:lang/... 路径前缀多语言;CSR 用 /home 无前缀)src/i18n/frameworkI18n.ts 同步 init;CSR 用 src/i18n/index.ts LanguageDetector 异步)src/utils/request),请求体 brotli 压缩(brotli-wasm)├── build/ # Vite 构建相关(插件、工具、分包/压缩/服务配置)
│ └── config/ # 细粒度 Vite 配置模块(chunks、build、plugins、server、optimize)
├── public/ # 静态资源
├── src/
│ ├── assets/ # 资源
│ │ └── iconify/ # 单色 single-color、多色 multi-color 图标
│ ├── components/ # 公共组件
│ ├── config/ # 应用与请求配置(含 request 拦截器、错误处理)
│ ├── defines/ # 枚举与常量
│ ├── hooks/ # 公共 Hooks
│ ├── i18n/ # 国际化配置
│ ├── layouts/ # 布局
│ ├── locales/ # 多语言文案(zh-CN、en-US、fa-IR)
│ ├── models/ # 全局状态 Model
│ ├── pages/ # 页面(按页面分目录,直接作为 route module)
│ ├── routes/ # framework 路由用的包装组件(langLayout、rootRedirect 等)
│ ├── services/ # API 接口(按模块分目录)
│ ├── styles/ # 全局样式
│ ├── utils/ # 工具与 request 封装
│ ├── root.tsx # HTML 外壳 + Provider 层(取代 index.html/App.tsx)
│ ├── routes.ts # framework 路由配置(含 /:lang 前缀)
│ ├── entry.client.tsx # 客户端入口(hydrateRoot,取代 main.tsx)
│ └── entry.server.tsx # 构建期预渲染入口
├── types/ # 全局类型与 env 类型
├── docs/SSG.md # SSG / framework 模式架构文档
├── react-router.config.ts # framework 模式配置(ssr:false + prerender)
├── vite.config.ts
└── package.json
locales,禁止在代码中硬编码src/defines/,请求在 src/services/ 按模块组织src/pages/ 下建目录、在 src/routes.ts 中注册路由、在 locales 补文案;若页面需预渲染,在 react-router.config.ts 的 prerender() 中加路径(详见 SSG 架构文档)src/models/,通过 createModel(hook, name) 创建。const user = userModel.useModel(),使用返回的状态与方法。autoImportModels 注入所有 Model 的 Provider。详见 src/utils/model/ 与现有 userModel、dialogModel、userConfigModel 实现。
src/assets/iconify/single-color/,会转为 currentColor,可用 className 控制颜色。src/assets/iconify/multi-color/,保留原色。import icon from '@/assets/iconify/single-color/xxx.svg',再 <Icon icon={icon} />(@iconify/react)。src/locales/ 下按语言分目录(zh-CN、en-US、fa-IR),每语言含 common、components、menus、pages 等模块。const { t } = useTranslation();,t('key') 或带命名空间的 key。src/utils/request,基础配置与拦截器在 src/config/request/(认证、加解密、错误处理)。src/services/,每模块可有 typings.d.ts + index.ts。import { fetchXxx } from '@/services/xxx',错误由统一错误处理兜底,可选 skipErrorHandler 自行处理。src/utils/localUtils、src/utils/sessionUtils 提供 createLocalTools / createSessionTools,支持按 key/value 加密与命名空间。两种渲染模式的产物目录与 nginx 配置不同,按实际构建的模式选择对应配置。多环境通过 build:dev / build:test / build:prod 与对应 .env.* 区分。
dist/client/(framework 模式产物结构)。ssr:false 为纯静态预渲染,无需常驻 Node 服务,对 CDN 加速零影响。react-router.config.ts 的 prerender() 中配置;未预渲染的路径由 SPA fallback(dist/client/index.html)承载。nginx 需先尝试命中预渲染静态页,再回落 SPA fallback(详见 SSG 架构文档):
server {
root /var/www/home-web/dist/client;
location / {
# 依次尝试:精确文件 → 目录 index(命中预渲染页) → flat 后缀 → 回落 SPA fallback
try_files $uri $uri/ $uri.html /index.html;
}
# 带 hash 的静态资源长缓存
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
dist/,仅有一个空壳 index.html,无预渲染文件,即标准单页应用部署。$uri/、$uri.html,产物里没有对应文件):
```nginx
server {
root /var/www/home-web/dist;location / {
try_files $uri /index.html;
}
# 带 hash 的静态资源长缓存 location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
} } ```