first commit
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Build & Development
|
||||
|
||||
```bash
|
||||
# WeChat mini-program
|
||||
npm run dev:weapp # Watch/dev build → weapp/
|
||||
npm run build:weapp # Production build → weapp/
|
||||
|
||||
# H5 (web)
|
||||
npm run dev:h5 # Watch/dev build → build/
|
||||
npm run build:h5 # Production build → build/
|
||||
```
|
||||
|
||||
Output directories are determined by `TARO_ENV`: for H5 it's `build/`, for all other platforms it matches the platform name (e.g., `weapp/`).
|
||||
|
||||
No test or lint scripts are configured. ESLint (`eslint-config-taro`) and Stylelint are installed but must be run manually.
|
||||
|
||||
## Architecture
|
||||
|
||||
This is a **Taro 3.6** cross-platform app using **React 18** (concurrent mode), **TypeScript**, and **Webpack 5**. It targets WeChat, Alipay, DingTalk, JD, Kwai, QQ, Baidu, Toutiao mini-programs, and H5 web.
|
||||
|
||||
### UI Library: `@antmjs/vantui`
|
||||
|
||||
The UI library is `@antmjs/vantui` (v3), a Taro-compatible port of Vant. Components are imported from `@antmjs/vantui` directly (e.g., `import { Button } from '@antmjs/vantui'`). The `babel-plugin-import` in `babel.config.js` handles on-demand style imports.
|
||||
|
||||
### Page Structure
|
||||
|
||||
Each page lives in `src/pages/<name>/` and consists of three files:
|
||||
|
||||
- `index.tsx` — page component (functional or class)
|
||||
- `index.config.ts` — page-level config (title, navigation style, etc.)
|
||||
- `index.less` — page styles
|
||||
|
||||
Pages must be registered in `src/app.config.ts` under the `pages` array.
|
||||
|
||||
### Path Alias
|
||||
|
||||
`@` maps to `src/` (configured in `config/index.js`).
|
||||
|
||||
### Theme & Global Styles
|
||||
|
||||
- `src/app.less` — global app styles (imported in `app.ts`)
|
||||
- `src/styles/index.less` — theme variable overrides for Vant UI. It imports `@antmjs/vantui/es/style/var.less` and uncomments/redefines Less variables to customize the theme. This file is injected into every `.less` file via Less `modifyVars` (configured in `config/index.js` under both `mini.lessLoaderOption` and `h5.lessLoaderOption`).
|
||||
|
||||
### Webpack Customizations (`config/webpack/`)
|
||||
|
||||
- **`commonChain.js`** — Overrides Taro's default `script` rule `exclude` so that Babel also processes these `node_modules` packages: `taro`, `inversify`, `@antmjs`, `react-spring`, `recoil`, `buffer`, `qrcode`. Do NOT include "taro" in the project name or all node_modules will be recompiled.
|
||||
- **`miniChain.js`** — Applied to mini-program builds. Adds:
|
||||
- `MiniFixPlugin` — fixes path param encoding differences between WeChat/Douyin and Alipay/DingTalk
|
||||
- `GlobalFixPlugin` — polyfills the `global` variable for Alipay, DingTalk, and Baidu mini-programs
|
||||
- **`h5Chain.js`** — Applied to H5 builds. Adds `H5FixPlugin` for H5 compatibility fixes.
|
||||
|
||||
### Build Config Layers
|
||||
|
||||
`config/index.js` exports a function that merges the base config with `config/development.js` or `config/production.js` based on `NODE_ENV`. Environment variables:
|
||||
|
||||
| Variable | Purpose | Default |
|
||||
|---|---|---|
|
||||
| `TARO_ENV` | Target platform (`weapp`, `h5`, `alipay`, etc.) | `weapp` |
|
||||
| `NODE_ENV` | Build mode | `production` |
|
||||
| `API_ENV` | API environment selector | `real` |
|
||||
|
||||
- `designWidth: 750` — all px values are converted to rpx at this ratio
|
||||
- `@tarojs/plugin-framework-react` is configured with `reactMode: "concurrent"` (React 18 concurrent features)
|
||||
- `browserslist` targets iOS 9+ for production
|
||||
|
||||
### App Entry
|
||||
|
||||
- `src/app.ts` — class-based App component, renders `this.props.children` (the current page)
|
||||
- `src/app.config.ts` — defines routes (`pages` array), window config, and app-level settings
|
||||
- `src/index.html` — H5 entry HTML template
|
||||
|
||||
## VantUI Component API Reference (v3.7)
|
||||
|
||||
This project uses `@antmjs/vantui` v3.7. The official docs: https://antmjs.github.io/vantui/main/
|
||||
|
||||
**Always check the actual type definitions** in `node_modules/@antmjs/vantui/types/` when unsure about props. Key API notes for commonly used components:
|
||||
|
||||
### Search
|
||||
- `shape`: `'square'` (default) | `'round'`
|
||||
- `background`: background color string (default `#FFFFFF`)
|
||||
- `onFocus`, `onBlur`, `onChange`, `onSearch`, `onClear`, `onCancel` — event callbacks
|
||||
- `leftIcon`, `rightIcon` — icon name or image URL
|
||||
- `showAction` + `actionText` — right-side action button
|
||||
|
||||
### Swiper (NOT the same as Taro's native Swiper)
|
||||
- `autoPlay` — auto-play interval in ms (0 = disabled). **Not** `autoplay`
|
||||
- `loop` — infinite loop mode. **Not** `circular`
|
||||
- `paginationColor` — indicator dot color. **Not** `indicatorColor`
|
||||
- `paginationVisible` — show/hide pagination dots
|
||||
- `duration` — animation duration (default 500)
|
||||
- `width` / `height` — card dimensions
|
||||
- **No** `indicatorActiveColor` prop — only one `paginationColor`
|
||||
- `onChange` callback: `(currPage: number) => void` (not an event object)
|
||||
|
||||
### SwiperItem
|
||||
- Minimal component, only `className` and `children`. No special props.
|
||||
|
||||
### Grid / GridItem
|
||||
- `Grid`: `columnNum`, `border`, `gutter`, `square`, `clickable`, `center`, `iconSize`
|
||||
- `GridItem`: `icon` (string), `text` (ReactNode), `iconColor`, `dot`, `info`/`badge`, `url` + `linkType`
|
||||
|
||||
### Tabs / Tab (v3.7)
|
||||
- `Tabs`:
|
||||
- `active` — current tab index (number | string)
|
||||
- `sticky` — enable sticky mode
|
||||
- `offsetTop` — sticky offset in px. **Not** `stickyOffsetTop`
|
||||
- `color`, `titleActiveColor`, `titleInactiveColor` — color props
|
||||
- `type`: `'line'` | `'card'`
|
||||
- `swipeable` — enable swipe gesture switching
|
||||
- `animated` — enable tab switch animation
|
||||
- `ellipsis` — text overflow ellipsis (default true)
|
||||
- **No** `lineWidth` or `lineHeight` props
|
||||
- `onChange`: `(e: { detail: { index: number; name?: string; title?: string } }) => void`
|
||||
- `Tab`: `title` (ReactNode), `name` (identifier), `dot`, `info`, `disabled`, `titleStyle`
|
||||
|
||||
### Image (VantUI Image, not Taro's native Image)
|
||||
- `src`, `fit` (`'contain' | 'cover' | 'fill' | 'widthFix' | 'heightFix' | 'none'`), `width`, `height`, `radius`
|
||||
- `round` — circular image (boolean)
|
||||
- `lazyLoad`, `showError`, `showLoading`
|
||||
- `renderLoading`, `renderError` — custom render slots
|
||||
|
||||
### Common VantUI pattern: Taro's native components vs VantUI components
|
||||
- Use `@tarojs/components` for: `View`, `Text`, `ScrollView`, `Image` (native, simpler)
|
||||
- Use `@antmjs/vantui` for: styled UI components (Search, Swiper, Tabs, Grid, Button, etc.)
|
||||
- VantUI component props extend Taro's `ViewProps`, so `onClick`/`onTap` and style props are always available
|
||||
|
||||
## Custom TabBar (`src/custom-tab-bar/`)
|
||||
|
||||
This project uses Taro's **custom tabBar** mechanism (`tabBar.custom: true` in `app.config.ts`). Key rules:
|
||||
|
||||
### Component location
|
||||
- The custom tabBar component MUST be at `src/custom-tab-bar/index.tsx` — this is a Taro convention, not configurable
|
||||
- Taro automatically renders this component on every tab page; do NOT import `<CustomTabBar />` in individual pages
|
||||
|
||||
### Do NOT use CoverView
|
||||
- `CoverView` / `CoverImage` have known bugs on real devices: invisible, click events don't bubble
|
||||
- Use regular `<View>` with `position: fixed; bottom: 0; z-index: 999` instead
|
||||
|
||||
### Active tab state
|
||||
- Taro creates a **new instance** of the tabBar component on each page, so `useState` resets on every tab switch
|
||||
- Derive the active tab from `Taro.getCurrentPages()` at render time — NOT from component state
|
||||
- Pattern: `const route = Taro.getCurrentPages()[last]?.route; const activeKey = TAB_LIST.find(t => route.includes(t.key))`
|
||||
|
||||
### Tab switching
|
||||
- Use `Taro.switchTab({ url: pagePath })` — this matches native tabBar behavior
|
||||
- The `pagePath` format must match the `tabBar.list[].pagePath` in `app.config.ts`
|
||||
|
||||
### Center "publish" button
|
||||
- The publish button is a UI-only element not in `tabBar.list`
|
||||
- It triggers a VantUI `<Popup>` rendered as a sibling of the tabBar, NOT nested inside it
|
||||
- The popup state can use `useState` since it's ephemeral and not shared across tabs
|
||||
Reference in New Issue
Block a user