# Template-Specific Constraints

> **Scope**: These constraints apply to **static deploy** template projects created via `meoo init`. Image deploy projects do not use Meoo templates and are not subject to these rules.

## Shared rules (all templates)

- Dev server: port 3015, `strictPort: true`, host `0.0.0.0` — NEVER change
- Build output: `dist/` with `index.html` entry — NEVER change `base`/`outDir`/`assetsDir`/`assetsInlineLimit`
- Base path: `./` (relative)
- Assets < 1MB inlined as dataURL
- HMR disabled (preview compatibility)
- Hash routing only
- Icons: `lucide-react` or inline SVG. Do NOT use `@iconify/react`
- Package manager: pnpm only
- No scss/sass
- No esbuild direct calls or binary dependencies
- No base64 images or binary files
- No Tailwind colors not defined in config
- No external CDN JS/CSS links
- No comments unless user requests them
- No emoji as icons
- Single file ≤ 260 lines
- MUST create standard multi-file SPA, NEVER single HTML
- All navigation: implement URL routes first, then UI (MANDATORY)
- Every tab/page must have a Route definition
- Run `pnpm run dev` after edits to verify zero compilation errors before delivering

## react-project (Webpack)

**Stack**: React 18 + Webpack 5 + Tailwind CSS 3

**Specific constraints**:
- webpack-dev-server must be 4.x, NOT 5.x
- `devServer.allowedHosts` must be `['all', '.alibaba-inc.com']`
- `devServer.historyApiFallback` must be configured for hash routing
- `HtmlWebpackPlugin` must use `inject: 'body'`
- After modifying webpack config, MUST restart dev server
- Route structure must be documented in AGENTS.md with URL mapping table
- All modes must be switchable via URL parameters (if user requested modes)

**Dev**: `pnpm dev` → `webpack serve --port 3015`
**Build**: `pnpm build` → `webpack --mode production`

## react-vite-project (Vite)

**Stack**: React 18 + Vite 5 + Tailwind CSS 3

**Specific constraints**:
- Do NOT switch to webpack
- No synchronous network requests during component rendering
- No modification to `package.json` fields marked `meoo-app-name` (system-managed)

**Vite config locked fields** (changing breaks deployment):
```
server.port = 3015
server.strictPort = true
server.host = '0.0.0.0'
base = './'
build.outDir = 'dist'
build.assetsDir = 'assets'
build.assetsInlineLimit = 1024 * 1024
```

**Dev**: `pnpm dev` → `vite --port 3015 --host 0.0.0.0 --strictPort`
**Build**: `pnpm build` → `tsc --noEmit && vite build`

## react-design (Design System)

**Stack**: React 19 + Vite 7 + Tailwind CSS 4 + shadcn/ui + TanStack Router

The most feature-rich template. 46 shadcn/ui components pre-installed with all Radix primitives.

**Specific constraints**:
- Path alias `@` → `src/` (enforced)
- Route files MUST go in `src/routes/`, using `createFileRoute`
- Root layout in `__root.tsx`
- `src/routeTree.gen.ts` is auto-generated by Vite plugin — NEVER edit manually. Run `pnpm run dev` after creating new route files to regenerate
- Do NOT `pnpm install` individual packages — shadcn is fully pre-installed
- Do NOT reinstall any Radix primitives (already included via shadcn)
- Do NOT install animation libraries — use CSS keyframes or pre-installed `tw-animate-css`
- Do NOT use inline conditional classes — use `cva` to define variants
- Prefer reusing pre-installed shadcn components over building from scratch
- New dependencies: modify `package.json` then run `pnpm install`
- New UI goes in new files; component/file names must be unique
- Do NOT modify `package.json`/`index.html` fields marked `meoo-app-name`

**Pre-installed shadcn/ui components**:
accordion, alert, alert-dialog, aspect-ratio, avatar, badge, breadcrumb, button, calendar, card, carousel, chart, checkbox, collapsible, command, context-menu, dialog, drawer, dropdown-menu, form, hover-card, input, input-otp, label, menubar, navigation-menu, pagination, popover, progress, radio-group, resizable, scroll-area, select, separator, sheet, sidebar, skeleton, slider, sonner, switch, table, tabs, textarea, toggle, toggle-group, tooltip

**Same Vite locked fields as react-vite-project.**

## vue-project

**Stack**: Vue 3 + Vite 5 + Pinia + Vue Router 4 + Tailwind CSS 3

**Critical constraint: ZERO third-party UI or icon libraries.**

**Explicitly forbidden packages**:
- UI: `element-plus`, `ant-design-vue`, `naive-ui`, `vuetify`, `primevue`, `@arco-design/web-vue`, `vant`
- Icons: `@element-plus/icons-vue`, `@ant-design/icons-vue`, `lucide-vue-next`, `@heroicons/vue`, `vue-feather`
- Auto-importers: `unplugin-vue-components` + `ElementPlusResolver` and similar

**What to do instead**: Build all UI (buttons, inputs, modals, tables, icons) from scratch using native HTML elements + Tailwind CSS. Icons must be inline SVG.

**Specific constraints**:
- Vue 3 Composition API, `<script setup lang="ts">` syntax enforced
- `dependencies` in package.json must NOT contain any UI/icon library

**Same Vite locked fields as react-vite-project.** Build uses `vue-tsc` instead of `tsc`.

## taro-project (Mini Program)

**Stack**: Taro 4.x + React 18 + Zustand + Tailwind CSS 4

**Critical constraint: No native HTML tags.** Use `@tarojs/components` exclusively.

**Specific constraints**:
- Path alias `@/*` → `src/*` (pre-configured)
- Home page path must be `pages/index/index`
- After modifying `app.config.ts`, MUST restart `pnpm run dev`
- Before task completion, MUST run `pnpm run validate && pnpm run dev`
- Class names must be string literals — dynamic concatenation won't be scanned/bundled

**Tailwind restrictions** (WeChat Mini Program compatibility):
- No arbitrary values: `w-[340px]`, `text-[14px]` — forbidden
- No hardcoded `style={{ width: '200px' }}` — `style` only for cross-platform fixes
- No hex colors in class names: `bg-[#562aff]` — use semantic tokens
- No `peer-*` / `group-*` modifiers
- No decimal values: `space-y-1.5`, `w-0.5` (except `gap-*`)
- No `has-*` variants
- No `[&>*...]` wildcard selectors
- No `[&>[data-...]]` attribute selectors  
- No `[&~...]` sibling selectors
- No `bg-color/N` / `bg-opacity-N`
- No remote `@import` in CSS files

**Other restrictions**:
- No `import '@iconify-json/mdi'` — bundles 7000+ JSON files
- No `color="currentColor"` on icon components — not inherited in mini programs
- No `import { supabase }` in pages/components/stores — all calls go through `src/api/`
- No `localStorage`/`sessionStorage`/`wx.setStorageSync` — use `Taro.*StorageSync`
- No pipe truncation on check commands: `tsc | head` forbidden
- TabBar: configure in `app.config.ts`, not manual UI. Must have ≥ 2 items (recommend ≤ 4)
- Don't use `<Button>` — use `<View onClick>` + Tailwind instead (native Button has uncontrollable default styles)
- Date/time/enum pickers: use `<Picker>`, not `<Input>`
- Bundle size ≤ 2MB

**Dev**: `pnpm dev` → `taro build --type h5 --watch` (port 3015)
**Build**: `pnpm build` → `taro build --type weapp`
