mirror of
https://github.com/zuiidea/antd-admin
synced 2026-10-30 13:23:49 +00:00
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:
@@ -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
@@ -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).
|
||||
Reference in New Issue
Block a user