docs: refine README for template-first onboarding

Focus root docs on init-antd-admin usage and keep template setup guidance fully in English with clearer CLI options.

Made-with: Cursor
This commit is contained in:
zuiidea
2026-04-28 17:43:29 +08:00
parent 0726321552
commit 8673d8398e
2 changed files with 78 additions and 214 deletions
+61 -197
View File
@@ -1,225 +1,89 @@
# Antd Admin
Balanced admin monorepo: MSW mocks, minimal RBAC, full CRUD, and Playwright E2E — built with React 19, Ant Design 6, and Vite+. Ship either an **English-only** app (`apps/basic`) or a **Lingui i18n** variant (`apps/with-lingui`); see [Templates](#templates) below.
A practical admin monorepo with two production-style templates, mock-first development, and test coverage.
[antd](https://github.com/ant-design/ant-design)
[react](https://react.dev)
[vite](https://viteplus.dev)
[TypeScript](https://www.typescriptlang.org/)
[GitHub issues](https://github.com/zuiidea/antd-admin/issues)
[GitHub stars](https://github.com/zuiidea/antd-admin/stargazers)
[License](http://opensource.org/licenses/MIT)
[PRs Welcome](https://github.com/zuiidea/antd-admin/pulls)
- **`apps/basic`**: English-only setup
- **`apps/with-lingui`**: Bilingual setup (`en` + `zh`) with Lingui
- **`apps/docs`**: Nextra documentation site
- **`packages/create`**: `init-antd-admin` scaffolding CLI
## Links
- [Ant Design](https://github.com/ant-design/ant-design)
- [React](https://react.dev)
- [Vite+](https://viteplus.dev)
- [TypeScript](https://www.typescriptlang.org/)
- [Issues](https://github.com/zuiidea/antd-admin/issues)
- [Stars](https://github.com/zuiidea/antd-admin/stargazers)
- [PRs Welcome](https://github.com/zuiidea/antd-admin/pulls)
- [License (MIT)](http://opensource.org/licenses/MIT)
## Tech Stack
| Category | Technology |
| --- | --- |
| Build tool | [Vite+](https://viteplus.dev) |
| UI | [Ant Design 6.x](https://ant.design) |
| Routing | [TanStack Router](https://tanstack.com/router) |
| Async state | [TanStack Query v5](https://tanstack.com/query) |
| Local state | [Zustand](https://zustand.docs.pmnd.rs) |
| Validation | [Zod v4](https://zod.dev) |
| i18n | [LinguiJS](https://lingui.dev) in `apps/with-lingui` |
| Mocking | [MSW 2.x](https://mswjs.io) |
| E2E tests | [Playwright](https://playwright.dev) |
| Language | TypeScript 5.9 (strict) |
| Category | Technology |
| ------------ | ------------------------------------------------------------------------------------------------------- |
| Build Tool | [Vite+](https://viteplus.dev) (VoidZero unified toolchain) |
| UI Framework | [Ant Design 6.x](https://ant.design) |
| Routing | [TanStack Router](https://tanstack.com/router) (file-based, type-safe) |
| Async State | [TanStack Query v5](https://tanstack.com/query) |
| Local State | [Zustand](https://zustand.docs.pmnd.rs) (persisted auth & settings) |
| Validation | [Zod v4](https://zod.dev) (schemas, API contracts, form validation) |
| i18n | [LinguiJS](https://lingui.dev) in `**apps/with-lingui` only** (`apps/basic` is English-only, no Lingui) |
| Icons | [lucide-react](https://lucide.dev/guide/packages/lucide-react) |
| API Mocking | [MSW 2.x](https://mswjs.io) (Service Worker based) |
| E2E Testing | [Playwright](https://playwright.dev) |
| Language | TypeScript 5.9 (strict mode) |
## Highlights
## Features
- **JWT Authentication** — Login with access/refresh token flow, persisted via Zustand
- **Dynamic Menu & RBAC** — Backend-driven sidebar menu with permission guards and 403 page
- **URL-First State** — Table search params (page, pageSize, keyword, sort) synced to URL
- **i18n (with-lingui app)** — LinguiJS with English (`en`) and Chinese (`zh`); Ant Design locales follow the active locale in `apps/with-lingui`
- **Dark Mode** — One-click toggle with Ant Design theme algorithm
- **Full Type Safety** — Zod schemas validate API boundaries at runtime where used
- **Zero-Config Mocking** — MSW intercepts API calls in development, no backend needed
- JWT login with access/refresh flow
- Backend-driven menu and permission guards
- URL-synced table state (pagination, sorting, search)
- Dark mode theme switching
- Mock-first local development (no backend required)
- Typed API boundaries and reusable CRUD patterns
## Templates
`npx init-antd-admin@latest` · `pnpm dlx init-antd-admin@latest`
| Template | Use when |
| --- | --- |
| `with-lingui` | You need multilingual UI (`en` + `zh`) and Lingui workflow |
| `basic` | You need a simpler English-only setup |
## `init-antd-admin` Usage
| Directory | Use when |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `[apps/with-lingui](./apps/with-lingui/)` | You want **LinguiJS** (en + zh), `.po` extract/compile, and a language switcher — this is the fuller reference stack. |
| `[apps/basic](./apps/basic/)` | You want the **same product surface** with **English-only** UI (no Lingui, fixed `en_US` for Ant Design). |
Use the scaffolding CLI to create a standalone app from official templates.
Pick one app directory, install, and run Vite+ from there:
### Interactive
```bash
cd apps/basic && vp install && vp dev
# or
cd apps/with-lingui && vp install && vp dev
npx init-antd-admin@latest
pnpm dlx init-antd-admin@latest
yarn dlx init-antd-admin@latest
bunx init-antd-admin@latest
```
### 文档站(Nextra)
中文使用文档位于 `**apps/docs**`(Next.js + Nextra)。在仓库根或该目录安装依赖后:
### Non-interactive examples
```bash
cd apps/docs && pnpm install && pnpm dev
pnpm dlx init-antd-admin@latest my-app --example basic -m pnpm
pnpm dlx init-antd-admin@latest my-app --example with-lingui --skip-install
```
浏览器打开 [http://localhost:3000](http://localhost:3000)。模板 Vite+ 应用仍为 [http://localhost:5173](http://localhost:5173)。开发与构建命令说明见 `[apps/docs/README.md](./apps/docs/README.md)`。
### Common options
Core Playwright flows (from the app you are working in):
| Option | Description |
| --- | --- |
| `[project-directory]` | Target folder |
| `-e, --example <name|url>` | Template source |
| `--example-path <path>` | Subpath inside remote repository |
| `-m, --package-manager <pm>` | `npm` / `pnpm` / `yarn` / `bun` |
| `--skip-install` | Skip dependency install |
| `--skip-transforms` | Skip rewrite transforms |
| `--no-git` | Skip git initialization |
```bash
cd apps/basic && pnpm run test:e2e:core
```
### Git hooks
提交前检查由仓库根目录 **`.githooks/pre-commit`** 按暂存路径分发到各子项目(在对应目录执行 `vp staged`,避免在仓库根找不到 `vite.config.ts`)。一次性启用:
```bash
pnpm run setup:git-hooks
```
说明见 [.githooks/README.md](./.githooks/README.md)。模板目录内的 `.vite-hooks` 仍保留给模板单独拷贝使用;在本仓库开发请使用上述根级钩子。
## Getting Started
### Prerequisites
- [Node.js](https://nodejs.org) >= 20
- [Vite+](https://viteplus.dev/guide/) CLI (`vp`)
### Install & Run
From the repository root, choose an app under `apps/` (see [Templates](#templates)), then:
```bash
cd apps/with-lingui # or: cd apps/basic
vp install
vp dev
```
Open [http://localhost:5173](http://localhost:5173) — you'll be redirected to the login page.
**Default credentials:** `admin` / `admin`
### Build
```bash
vp build
vp preview
```
### E2E Tests
Run from the app package (example: `apps/basic`):
```bash
cd apps/basic
pnpm run test:e2e
pnpm run test:e2e:core
pnpm run test:e2e:ui # interactive UI mode
```
`test:e2e:core` runs the scaffold's highest-value flows only: login and users CRUD.
## Project Structure
```
src/
├── api/ # Zod schemas, endpoint constants, type exports
│ ├── schemas.ts # Domain models (User, AuthTokens, MenuItem, etc.)
│ ├── auth.ts # Auth endpoint constants
│ └── user.ts # User CRUD endpoint constants
├── components/
│ ├── Aurora/ # Login background effect
│ ├── Auth/ # Auth (permission gate): index.tsx
│ ├── DataTable/ # Shared table shell, skeleton, empty state
│ ├── FilterToolbar/ # Shared filter/action toolbar
│ ├── FormModal/ # Reusable modal + form shell
│ ├── Icon/ # Shared icons and theme toggle icon
│ └── Layout/ # Admin shell (sidebar, header, main)
│ ├── MainLayout/ # Main layout shell: index.tsx
│ ├── AppFooter/ # Login footer: Powered by + GitHub → zuiidea/antd-admin
│ ├── Sidebar/ # Dynamic menu sidebar: index.tsx
│ ├── UserMenu/ # User dropdown in sidebar: index.tsx + index.css
│ └── Header/ # Top bar: index.tsx
├── hooks/
│ ├── tokenBuilders.ts # Shared Ant Design token/config builders
│ ├── useAppTheme.ts # Theme selection hook (ConfigProvider)
│ ├── usePermission.ts # Permission check hook
│ └── useResourceCRUD.ts # Shared CRUD query/mutation wiring
├── utils/
│ ├── constants.ts # API base URL, static assets
│ └── http.ts # HTTP client with JWT injection & error handling
├── locales/ # LinguiJS catalogs (.po + compiled .js)
│ ├── en/messages.po
│ └── zh/messages.po
├── mocks/
│ ├── browser.ts # MSW worker setup
│ ├── createHandler.ts # Shared MSW success/error/delay helpers
│ ├── data.ts # Mock seed data (users, menus)
│ ├── utils.ts # Mock-only helpers (filters, pagination, demo avatar URLs)
│ └── handlers/ # Request handlers (auth, user CRUD)
├── routes/ # TanStack Router file-based routes
│ ├── __root.tsx # Root layout (QueryClient, ConfigProvider, I18n)
│ ├── _auth.tsx # Auth guard layout (redirects to /login)
│ ├── _auth/dashboard/index.tsx
│ ├── _auth/users/index.tsx # Full CRUD with URL-synced search params
│ ├── _auth/403/index.tsx
│ ├── login/index.tsx
│ ├── 404/index.tsx
│ └── index.tsx # Redirects / → /login
├── stores/
│ ├── auth.ts # Auth store (tokens, user, menus, permissions)
│ ├── createPersistentStore.ts # Shared persisted-store factory
│ └── settings.ts # Settings store (darkMode, locale, sidebar)
└── main.tsx # Entry point (MSW init → React render)
tests/
└── e2e/ # Playwright E2E tests
├── helpers.ts
├── login.spec.ts
└── users.spec.ts
```
## Internationalization (i18n)
The project uses [LinguiJS](https://lingui.dev) with compile-time macros. Locales: `**en**` (source) and `**zh**`.
### Workflow
```bash
vp run i18n:extract
vp run i18n:compile
```
Ant Design strings follow the active locale via `ConfigProvider` in `__root.tsx`.
## Extending the template
- **Real backend:** Point `VITE_API_BASE_URL` in env and disable or remove MSW in `main.tsx` when you no longer need mocks.
- **Drop i18n:** Remove Lingui packages, vite/swc plugins, and replace `t` macros with plain strings (larger refactor).
## Developer Notes
- Prefer Vite+ commands for installs, checks, and scripts. This repo is configured around `vp`.
- Run `vp check --no-fmt` for type/lint validation.
- Core regression coverage lives in the login and users E2E flows.
## Pages
| Route | Description |
| ------------ | ----------------------------------------------------------- |
| `/login` | Login form with validation |
| `/dashboard` | Statistics overview cards |
| `/users` | User CRUD table with search, pagination, create/edit/delete |
| `/403` | Forbidden error page |
| `/404` | Not found error page |
For package-specific details, see [`packages/create/README.md`](./packages/create/README.md).
Production docs: [https://antd-admin-doc.zuiidea.top](https://antd-admin-doc.zuiidea.top)
## License
+17 -17
View File
@@ -28,17 +28,17 @@ pnpm dlx init-antd-admin@latest my-app --example basic --skip-install
### CLI options
| Option | Description |
| -------------------------- | ----------------------------------------------------- |
| `[project-directory]` | Target folder (relative path or `.`; empty dirs only) |
| `-e, --example <name|url>` | Example id from the built-in list, or a template URL |
| `--example-path <path>` | Extra path inside the repo when using a URL |
| `-m, --package-manager` | `npm` \| `yarn` \| `pnpm` \| `bun` |
| `--skip-install` | Do not run install after scaffold |
| `--skip-transforms` | Skip rewrites (e.g. `package.json` name) |
| `--no-git` | Do not run `git init` |
| `-v, --version` | Print CLI version |
| `-h, --help` | Print help |
| Option | Description |
| ----------------------- | ----------------------------------------------------- |
| `[project-directory]` | Target folder (relative path or `.`; empty dirs only) |
| `-e, --example <name | url>` |
| `--example-path <path>` | Extra path inside the repo when using a URL |
| `-m, --package-manager` | `npm` | `yarn` | `pnpm` | `bun` |
| `--skip-install` | Do not run install after scaffold |
| `--skip-transforms` | Skip rewrites (e.g. `package.json` name) |
| `--no-git` | Do not run `git init` |
| `-v, --version` | Print CLI version |
| `-h, --help` | Print help |
Run `init-antd-admin --help` for the full help text.
@@ -74,14 +74,14 @@ Design and implementation notes live under `docs/specs/` in the monorepo (e.g. `
CI workflow: `.github/workflows/publish-init-antd-admin.yml` in the monorepo (open on GitHub from the default branch).
1. Add repository secret **`NPM_TOKEN`** (npm automation or granular token with publish permission for `init-antd-admin`).
2. Bump **`version`** in this directory’s `package.json`, commit, then either:
- **Actions → “Publish init-antd-admin” → Run workflow**, or
- Push tag **`init-antd-admin-v<version>`** (e.g. `init-antd-admin-v1.0.3` must match `package.json` version `1.0.3`).
3. Push a matching **`v<version>`** tag on the monorepo (e.g. `v1.0.3`) if users rely on the default template ref `v${version}` from the CLI.
1. Add repository secret `**NPM_TOKEN**` (npm automation or granular token with publish permission for `init-antd-admin`).
2. Bump `**version**` in this directory’s `package.json`, commit, then either:
- **Actions → “Publish init-antd-admin” → Run workflow**, or
- Push tag `**init-antd-admin-v<version>`** (e.g. `init-antd-admin-v1.0.3` must match `package.json` version `1.0.3`).
3. Push a matching `**v<version>**` tag on the monorepo (e.g. `v1.0.3`) if users rely on the default template ref `v${version}` from the CLI.
If **provenance** publish fails from your machine, publish from CI (this workflow passes `--provenance`) or see [npm provenance docs](https://docs.npmjs.com/generating-provenance-statements).
## License
MIT (same as the parent repository).
MIT (same as the parent repository).