@coze-arch/cli 0.0.1-alpha.de5a13 → 0.0.1-alpha.deaedf

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +1 -0
  2. package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +1 -1
  3. package/lib/__templates__/expo/client/components/Screen.tsx +2 -2
  4. package/lib/__templates__/expo/client/eslint.config.mjs +7 -0
  5. package/lib/__templates__/expo/client/metro.config.js +3 -0
  6. package/lib/__templates__/expo/client/scripts/install-missing-deps.js +10 -10
  7. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/index.js +9 -0
  8. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/rule.js +112 -0
  9. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/tech.md +94 -0
  10. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/index.js +9 -0
  11. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/rule.js +120 -0
  12. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/tech.md +58 -0
  13. package/lib/__templates__/expo/pnpm-lock.yaml +8 -5
  14. package/lib/__templates__/expo/server/package.json +1 -1
  15. package/lib/__templates__/native-static/.coze +11 -0
  16. package/lib/__templates__/native-static/index.html +33 -0
  17. package/lib/__templates__/native-static/styles/main.css +136 -0
  18. package/lib/__templates__/native-static/template.config.js +22 -0
  19. package/lib/__templates__/nextjs/.babelrc +3 -0
  20. package/lib/__templates__/nextjs/README.md +5 -0
  21. package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
  22. package/lib/__templates__/nextjs/next.config.ts +1 -2
  23. package/lib/__templates__/nextjs/package.json +3 -6
  24. package/lib/__templates__/nextjs/pnpm-lock.yaml +1036 -10
  25. package/lib/__templates__/nextjs/scripts/build.sh +4 -1
  26. package/lib/__templates__/nextjs/scripts/dev.sh +8 -2
  27. package/lib/__templates__/nextjs/scripts/start.sh +7 -1
  28. package/lib/__templates__/nextjs/src/app/layout.tsx +1 -1
  29. package/lib/__templates__/nextjs/src/app/page.tsx +1 -2
  30. package/lib/__templates__/nextjs/src/server.ts +35 -0
  31. package/lib/__templates__/nextjs/tsconfig.json +1 -1
  32. package/lib/__templates__/nuxt-vue/.coze +12 -0
  33. package/lib/__templates__/nuxt-vue/README.md +73 -0
  34. package/lib/__templates__/nuxt-vue/_gitignore +24 -0
  35. package/lib/__templates__/nuxt-vue/_npmrc +23 -0
  36. package/lib/__templates__/nuxt-vue/app/app.vue +6 -0
  37. package/lib/__templates__/nuxt-vue/app/pages/index.vue +23 -0
  38. package/lib/__templates__/nuxt-vue/assets/css/main.css +24 -0
  39. package/lib/__templates__/nuxt-vue/nuxt.config.ts +116 -0
  40. package/lib/__templates__/nuxt-vue/package.json +35 -0
  41. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +8759 -0
  42. package/lib/__templates__/nuxt-vue/postcss.config.mjs +8 -0
  43. package/lib/__templates__/nuxt-vue/public/favicon.ico +0 -0
  44. package/lib/__templates__/nuxt-vue/public/robots.txt +2 -0
  45. package/lib/__templates__/nuxt-vue/scripts/build.sh +14 -0
  46. package/lib/__templates__/nuxt-vue/scripts/dev.sh +39 -0
  47. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +14 -0
  48. package/lib/__templates__/nuxt-vue/scripts/start.sh +21 -0
  49. package/lib/__templates__/nuxt-vue/server/api/hello.ts +10 -0
  50. package/lib/__templates__/nuxt-vue/server/middleware/logger.ts +10 -0
  51. package/lib/__templates__/nuxt-vue/server/routes/health.ts +10 -0
  52. package/lib/__templates__/nuxt-vue/tailwind.config.js +13 -0
  53. package/lib/__templates__/nuxt-vue/template.config.js +87 -0
  54. package/lib/__templates__/nuxt-vue/tsconfig.json +18 -0
  55. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +107 -37
  56. package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +24 -1
  57. package/lib/__templates__/taro/README.md +138 -62
  58. package/lib/__templates__/taro/config/index.ts +105 -41
  59. package/lib/__templates__/taro/config/prod.ts +4 -5
  60. package/lib/__templates__/taro/eslint.config.mjs +82 -4
  61. package/lib/__templates__/taro/package.json +23 -7
  62. package/lib/__templates__/taro/patches/@tarojs__plugin-mini-ci@4.1.9.patch +30 -0
  63. package/lib/__templates__/taro/pnpm-lock.yaml +1198 -214
  64. package/lib/__templates__/taro/server/package.json +3 -1
  65. package/lib/__templates__/taro/src/app.css +140 -47
  66. package/lib/__templates__/taro/src/app.tsx +9 -0
  67. package/lib/__templates__/taro/src/components/ui/accordion.tsx +159 -0
  68. package/lib/__templates__/taro/src/components/ui/alert-dialog.tsx +260 -0
  69. package/lib/__templates__/taro/src/components/ui/alert.tsx +60 -0
  70. package/lib/__templates__/taro/src/components/ui/aspect-ratio.tsx +36 -0
  71. package/lib/__templates__/taro/src/components/ui/avatar.tsx +84 -0
  72. package/lib/__templates__/taro/src/components/ui/badge.tsx +37 -0
  73. package/lib/__templates__/taro/src/components/ui/breadcrumb.tsx +117 -0
  74. package/lib/__templates__/taro/src/components/ui/button-group.tsx +83 -0
  75. package/lib/__templates__/taro/src/components/ui/button.tsx +67 -0
  76. package/lib/__templates__/taro/src/components/ui/calendar.tsx +394 -0
  77. package/lib/__templates__/taro/src/components/ui/card.tsx +108 -0
  78. package/lib/__templates__/taro/src/components/ui/carousel.tsx +228 -0
  79. package/lib/__templates__/taro/src/components/ui/checkbox.tsx +58 -0
  80. package/lib/__templates__/taro/src/components/ui/code-block.tsx +169 -0
  81. package/lib/__templates__/taro/src/components/ui/collapsible.tsx +71 -0
  82. package/lib/__templates__/taro/src/components/ui/command.tsx +385 -0
  83. package/lib/__templates__/taro/src/components/ui/context-menu.tsx +614 -0
  84. package/lib/__templates__/taro/src/components/ui/dialog.tsx +256 -0
  85. package/lib/__templates__/taro/src/components/ui/drawer.tsx +192 -0
  86. package/lib/__templates__/taro/src/components/ui/dropdown-menu.tsx +561 -0
  87. package/lib/__templates__/taro/src/components/ui/field.tsx +228 -0
  88. package/lib/__templates__/taro/src/components/ui/hover-card.tsx +282 -0
  89. package/lib/__templates__/taro/src/components/ui/input-group.tsx +197 -0
  90. package/lib/__templates__/taro/src/components/ui/input-otp.tsx +136 -0
  91. package/lib/__templates__/taro/src/components/ui/input.tsx +56 -0
  92. package/lib/__templates__/taro/src/components/ui/label.tsx +24 -0
  93. package/lib/__templates__/taro/src/components/ui/menubar.tsx +595 -0
  94. package/lib/__templates__/taro/src/components/ui/navigation-menu.tsx +264 -0
  95. package/lib/__templates__/taro/src/components/ui/pagination.tsx +118 -0
  96. package/lib/__templates__/taro/src/components/ui/popover.tsx +291 -0
  97. package/lib/__templates__/taro/src/components/ui/portal.tsx +19 -0
  98. package/lib/__templates__/taro/src/components/ui/progress.tsx +28 -0
  99. package/lib/__templates__/taro/src/components/ui/radio-group.tsx +64 -0
  100. package/lib/__templates__/taro/src/components/ui/resizable.tsx +346 -0
  101. package/lib/__templates__/taro/src/components/ui/scroll-area.tsx +34 -0
  102. package/lib/__templates__/taro/src/components/ui/select.tsx +438 -0
  103. package/lib/__templates__/taro/src/components/ui/separator.tsx +30 -0
  104. package/lib/__templates__/taro/src/components/ui/sheet.tsx +262 -0
  105. package/lib/__templates__/taro/src/components/ui/skeleton.tsx +17 -0
  106. package/lib/__templates__/taro/src/components/ui/slider.tsx +203 -0
  107. package/lib/__templates__/taro/src/components/ui/sonner.tsx +1 -0
  108. package/lib/__templates__/taro/src/components/ui/switch.tsx +55 -0
  109. package/lib/__templates__/taro/src/components/ui/table.tsx +142 -0
  110. package/lib/__templates__/taro/src/components/ui/tabs.tsx +114 -0
  111. package/lib/__templates__/taro/src/components/ui/textarea.tsx +54 -0
  112. package/lib/__templates__/taro/src/components/ui/toast.tsx +517 -0
  113. package/lib/__templates__/taro/src/components/ui/toggle-group.tsx +120 -0
  114. package/lib/__templates__/taro/src/components/ui/toggle.tsx +77 -0
  115. package/lib/__templates__/taro/src/components/ui/tooltip.tsx +455 -0
  116. package/lib/__templates__/taro/src/lib/hooks/use-keyboard-offset.ts +37 -0
  117. package/lib/__templates__/taro/src/lib/measure.ts +115 -0
  118. package/lib/__templates__/taro/src/lib/platform.ts +12 -0
  119. package/lib/__templates__/taro/src/lib/utils.ts +6 -0
  120. package/lib/__templates__/taro/src/presets/dev-debug.ts +23 -0
  121. package/lib/__templates__/taro/src/presets/h5-container.tsx +15 -0
  122. package/lib/__templates__/taro/src/presets/h5-navbar.tsx +238 -0
  123. package/lib/__templates__/taro/src/presets/h5-styles.ts +220 -0
  124. package/lib/__templates__/taro/src/presets/index.tsx +18 -0
  125. package/lib/__templates__/templates.json +43 -0
  126. package/lib/__templates__/vite/README.md +190 -11
  127. package/lib/__templates__/vite/_gitignore +1 -0
  128. package/lib/__templates__/vite/eslint.config.mjs +6 -1
  129. package/lib/__templates__/vite/package.json +14 -5
  130. package/lib/__templates__/vite/pnpm-lock.yaml +768 -24
  131. package/lib/__templates__/vite/scripts/build.sh +4 -1
  132. package/lib/__templates__/vite/scripts/dev.sh +9 -2
  133. package/lib/__templates__/vite/scripts/start.sh +9 -3
  134. package/lib/__templates__/vite/server/routes/index.ts +31 -0
  135. package/lib/__templates__/vite/server/server.ts +65 -0
  136. package/lib/__templates__/vite/server/vite.ts +67 -0
  137. package/lib/__templates__/vite/tsconfig.json +4 -3
  138. package/lib/__templates__/vite/vite.config.ts +5 -0
  139. package/lib/cli.js +124 -103
  140. package/package.json +7 -3
  141. package/lib/__templates__/taro/src/app.ts +0 -14
  142. package/lib/__templates__/taro/src/utils/h5-styles.ts +0 -22
  143. package/lib/__templates__/taro/src/utils/wx-debug.ts +0 -23
@@ -10,7 +10,7 @@
10
10
  - **样式**: TailwindCSS 4.1.18
11
11
  - **Tailwind 适配层**: weapp-tailwindcss 4.9.2
12
12
  - **状态管理**: Zustand 5.0.9
13
- - **图标库**: lucide-react 0.511.0
13
+ - **图标库**: lucide-react-taro latest
14
14
  - **工程化**: Vite 4.2.0
15
15
  - **包管理**: pnpm
16
16
  - **运行时**: Node.js >= 18
@@ -28,14 +28,16 @@
28
28
  │ ├── dev.ts # 开发环境配置
29
29
  │ └── prod.ts # 生产环境配置
30
30
  ├── server/ # NestJS 后端服务
31
- │ └── src/
31
+ │ └── src/
32
32
  │ ├── main.ts # 服务入口
33
33
  │ ├── app.module.ts # 根模块
34
34
  │ ├── app.controller.ts # 应用控制器
35
35
  │ └── app.service.ts # 应用服务
36
36
  ├── src/ # 前端源码
37
37
  │ ├── pages/ # 页面组件
38
+ │ ├── presets/ # 框架预置逻辑(无需读取,如无必要不改动)
38
39
  │ ├── utils/ # 工具函数
40
+ │ ├── network.ts # 封装好的网络请求工具
39
41
  │ ├── app.ts # 应用入口
40
42
  │ ├── app.config.ts # 应用配置
41
43
  │ └── app.css # 全局样式
@@ -103,56 +105,39 @@ pnpm preview:weapp # 构建并生成预览小程序二维码
103
105
  pnpm new # 交互式创建页面/组件
104
106
  ```
105
107
 
106
- ### 常用 Taro 组件
108
+ ### 组件库
109
+
110
+ #### UI 组件
107
111
 
108
- 引入方式
112
+ UI 组件位于 `@/components/ui`,推荐按需引入:
109
113
 
110
114
  ```typescript
111
- import { Text } from '@tarojs/components'
112
- ```
113
- - 基础组件
114
- - Text
115
- - Icon
116
- - Progress
117
- - RichText
118
- - 表单组件
119
- - Button
120
- - Checkbox
121
- - CheckboxGroup
122
- - Editor
123
- - Form
124
- - Input
125
- - Label
126
- - Picker
127
- - PickerView
128
- - PickerViewColumn
129
- - Radio
130
- - RadioGroup
131
- - Slider
132
- - Switch
133
- - Textarea
134
- - 导航组件
135
- - FunctionalPageNavigator
136
- - NavigationBar
137
- - Navigator
138
- - TabItem
139
- - Tabs
140
- - 媒体组件
141
- - Camera
142
- - Image
143
- - Video
144
- - 视图容器
145
- - ScrollView
146
- - Swiper
147
- - SwiperItem
148
- - View
115
+ import { Button } from '@/components/ui/button'
116
+ import { Card, CardContent } from '@/components/ui/card'
117
+ ```
118
+
119
+ UI 组件列表:
120
+
121
+ Accordion,Alert,AlertDialog,AspectRatio,Avatar,Badge,Breadcrumb,Button,ButtonGroup,Calendar,Card,Carousel,Checkbox,CodeBlock,Collapsible,Command,ContextMenu,Dialog,Drawer,DropdownMenu,Field,HoverCard,Input,InputGroup,InputOTP,Label,Menubar,NavigationMenu,Pagination,Popover,Portal,Progress,RadioGroup,Resizable,ScrollArea,Select,Separator,Sheet,Skeleton,Slider,Sonner,Switch,Table,Tabs,Textarea,Toast,Toggle,ToggleGroup,Tooltip
122
+
123
+ #### Taro 原生组件
124
+
125
+ 可以使用的 Taro 组件(UI 未覆盖)
126
+
127
+ ```typescript
128
+ import { View, Text, Icon, Image } from '@tarojs/components'
129
+ ```
130
+
131
+ Taro 原生组件列表:
132
+
133
+ Text,Icon,RichText,CheckboxGroup,Editor,Form,Picker,PickerView,PickerViewColumn,Radio,FunctionalPageNavigator,NavigationBar,Navigator,TabItem,Camera,Image,Video,ScrollView,Swiper,SwiperItem,View
149
134
 
150
135
  ### 路径别名
151
136
 
152
137
  项目配置了 `@/*` 路径别名指向 `src/*`:
153
138
 
154
139
  ```typescript
155
- import { SomeComponent } from '@/components/SomeComponent'
140
+ import { SomeComponent } from '@/components/some-component'
156
141
  import { useUserStore } from '@/stores/user'
157
142
  ```
158
143
 
@@ -162,9 +147,18 @@ import { useUserStore } from '@/stores/user'
162
147
 
163
148
  ```tsx
164
149
  // src/pages/example/index.tsx
165
- import { View, Text } from '@tarojs/components'
150
+ import { View } from '@tarojs/components'
166
151
  import { useLoad, useDidShow } from '@tarojs/taro'
167
152
  import type { FC } from 'react'
153
+ import { Button } from '@/components/ui/button'
154
+ import {
155
+ Card,
156
+ CardContent,
157
+ CardDescription,
158
+ CardFooter,
159
+ CardHeader,
160
+ CardTitle,
161
+ } from '@/components/ui/card'
168
162
  import './index.css'
169
163
 
170
164
  const ExamplePage: FC = () => {
@@ -177,8 +171,25 @@ const ExamplePage: FC = () => {
177
171
  })
178
172
 
179
173
  return (
180
- <View className="flex flex-col items-center p-4">
181
- <Text className="text-lg font-bold">Hello Taro!</Text>
174
+ <View className="p-4">
175
+ <Card>
176
+ <CardHeader>
177
+ <CardTitle>Hello Taro!</CardTitle>
178
+ <CardDescription>
179
+ 页面布局用 Taro 基础组件,交互与视觉优先用项目内置 UI 组件。
180
+ </CardDescription>
181
+ </CardHeader>
182
+ <CardContent>
183
+ <View className="text-sm text-muted-foreground">
184
+ 组件位于 src/components/ui,推荐按需从 @/components/ui/* 引入。
185
+ </View>
186
+ </CardContent>
187
+ <CardFooter className="justify-end">
188
+ <Button size="sm" onClick={() => console.log('clicked')}>
189
+ 点击
190
+ </Button>
191
+ </CardFooter>
192
+ </Card>
182
193
  </View>
183
194
  )
184
195
  }
@@ -237,8 +248,8 @@ Network 是对 Taro.request、Taro.uploadFile、Taro.downloadFile 的封装,
237
248
  import { Network } from '@/network'
238
249
 
239
250
  // GET 请求
240
- const data = await Network.request({
241
- url: '/api/hello'
251
+ const data = await Network.request({
252
+ url: '/api/hello'
242
253
  })
243
254
 
244
255
  // POST 请求
@@ -267,8 +278,8 @@ await Network.downloadFile({
267
278
  import Taro from '@tarojs/taro'
268
279
 
269
280
  // ❌ 会导致自动域名拼接无法生效,除非是特殊指定域名
270
- const data = await Network.request({
271
- url: 'http://localhost/api/hello'
281
+ const data = await Network.request({
282
+ url: 'http://localhost/api/hello'
272
283
  })
273
284
 
274
285
  // ❌ 不要直接使用 Taro.request
@@ -344,23 +355,29 @@ const router = useRouter()
344
355
  const { id } = router.params
345
356
  ```
346
357
 
347
- ### 图标使用 (lucide-react)
358
+ ### 图标使用 (lucide-react-taro)
348
359
 
349
- 项目集成了 [lucide-react](https://lucide.dev/) 图标库,提供丰富的 SVG 图标:
360
+ **IMPORTANT: 禁止使用 lucide-react,必须使用 lucide-react-taro 替代。**
361
+
362
+ lucide-react-taro 是 Lucide 图标库的 Taro 适配版本,专为小程序环境优化,API 与 lucide-react 一致:
350
363
 
351
364
  ```tsx
352
365
  import { View } from '@tarojs/components'
353
- import { Home, Settings, User, Search, Heart, Star } from 'lucide-react'
366
+ import { House, Settings, User, Search, Camera, Zap } from 'lucide-react-taro'
354
367
 
355
368
  const IconDemo = () => {
356
369
  return (
357
370
  <View className="flex gap-4">
358
- <Home size={24} color="#333" />
359
- <Settings size={24} className="text-blue-500" />
360
- <User size={20} strokeWidth={1.5} />
361
- <Search size={24} />
362
- <Heart size={24} fill="red" color="red" />
363
- <Star size={24} className="text-yellow-500" />
371
+ {/* 基本用法 */}
372
+ <House />
373
+ {/* 自定义尺寸和颜色 */}
374
+ <Settings size={32} color="#1890ff" />
375
+ {/* 自定义描边宽度 */}
376
+ <User size={24} strokeWidth={1.5} />
377
+ {/* 绝对描边宽度(描边不随 size 缩放) */}
378
+ <Camera size={48} strokeWidth={2} absoluteStrokeWidth />
379
+ {/* 组合使用 */}
380
+ <Zap size={32} color="#ff6b00" strokeWidth={1.5} className="my-icon" />
364
381
  </View>
365
382
  )
366
383
  }
@@ -368,12 +385,68 @@ const IconDemo = () => {
368
385
 
369
386
  常用属性:
370
387
  - `size` - 图标大小(默认 24)
371
- - `color` - 图标颜色
388
+ - `color` - 图标颜色(默认 currentColor,小程序中建议显式设置)
372
389
  - `strokeWidth` - 线条粗细(默认 2)
373
- - `className` - 支持 Tailwind 类名
390
+ - `absoluteStrokeWidth` - 绝对描边宽度,启用后描边不随 size 缩放
391
+ - `className` / `style` - 自定义样式
374
392
 
375
393
  更多图标请访问:https://lucide.dev/icons
376
394
 
395
+ ### TabBar 图标生成 (CLI 工具)
396
+
397
+ **IMPORTANT: 微信小程序的 TabBar 不支持 base64 或 SVG 图片,必须使用本地 PNG 文件。**
398
+
399
+ lucide-react-taro 提供了 CLI 工具来生成 TabBar 所需的 PNG 图标:
400
+
401
+ ```bash
402
+ # 生成带选中状态的图标
403
+ npx taro-lucide-tabbar House Settings User -c "#999999" -a "#1890ff"
404
+
405
+ # 指定输出目录和尺寸
406
+ npx taro-lucide-tabbar House Settings User -c "#999999" -a "#1890ff" -o ./src/assets/tabbar -s 81
407
+ ```
408
+
409
+ CLI 参数:
410
+ - `--color, -c` (默认 #000000): 图标颜色
411
+ - `--active-color, -a`: 选中状态颜色
412
+ - `--size, -s` (默认 81): 图标尺寸
413
+ - `--output, -o` (默认 ./tabbar-icons): 输出目录
414
+ - `--stroke-width` (默认 2): 描边宽度
415
+
416
+ 在 `app.config.ts` 中使用生成的图标:
417
+
418
+ > IMPORTANT:iconPath 和 selectedIconPath 必须以 `./` 开头,否则图标无法渲染
419
+
420
+ ```typescript
421
+ export default defineAppConfig({
422
+ tabBar: {
423
+ color: '#999999',
424
+ selectedColor: '#1890ff',
425
+ backgroundColor: '#ffffff',
426
+ borderStyle: 'black',
427
+ list: [
428
+ {
429
+ pagePath: 'pages/index/index',
430
+ text: '首页',
431
+ iconPath: './assets/tabbar/house.png',
432
+ selectedIconPath: './assets/tabbar/house-active.png',
433
+ },
434
+ {
435
+ pagePath: 'pages/settings/index',
436
+ text: '设置',
437
+ iconPath: './assets/tabbar/settings.png',
438
+ selectedIconPath: './assets/tabbar/settings-active.png',
439
+ },
440
+ {
441
+ pagePath: 'pages/user/index',
442
+ text: '用户',
443
+ iconPath: './assets/tabbar/user.png',
444
+ selectedIconPath: './assets/tabbar/user-active.png',
445
+ },
446
+ ],
447
+ },
448
+ })
449
+
377
450
  ### Tailwind CSS 样式开发
378
451
 
379
452
  IMPORTANT:必须使用 tailwindcss 实现样式,只有在必要情况下才能 fallback 到 css / less
@@ -381,10 +454,13 @@ IMPORTANT:必须使用 tailwindcss 实现样式,只有在必要情况下才
381
454
  > 项目已集成 Tailwind CSS 4.x + weapp-tailwindcss,支持跨端原子化样式:
382
455
 
383
456
  ```tsx
457
+ import { View, Text } from '@tarojs/components'
458
+ import { Button } from '@/components/ui/button'
459
+
384
460
  <View className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
385
461
  <Text className="text-2xl font-bold text-blue-600 mb-4">标题</Text>
386
462
  <View className="w-full px-4">
387
- <Button className="w-full bg-blue-500 text-white rounded-lg py-3">
463
+ <Button className="w-full" size="lg">
388
464
  按钮
389
465
  </Button>
390
466
  </View>
@@ -1,22 +1,76 @@
1
+ import fs from 'node:fs';
1
2
  import path from 'node:path';
2
- import dotenv from 'dotenv';
3
3
 
4
4
  import tailwindcss from '@tailwindcss/postcss';
5
5
  import { UnifiedViteWeappTailwindcssPlugin } from 'weapp-tailwindcss/vite';
6
6
  import { defineConfig, type UserConfigExport } from '@tarojs/cli';
7
7
  import type { PluginItem } from '@tarojs/taro/types/compile/config/project';
8
-
9
- // 加载环境变量
10
- dotenv.config({ path: path.resolve(__dirname, '../.env.local') });
11
-
8
+ import dotenv from 'dotenv';
12
9
  import devConfig from './dev';
13
10
  import prodConfig from './prod';
14
11
  import pkg from '../package.json';
15
12
 
13
+ dotenv.config({ path: path.resolve(__dirname, '../.env.local') });
14
+
15
+ const generateTTProjectConfig = () => {
16
+ const config = {
17
+ miniprogramRoot: './',
18
+ projectname: '<%= appName %>',
19
+ appid: process.env.TARO_APP_TT_APPID || '',
20
+ setting: {
21
+ urlCheck: false,
22
+ es6: false,
23
+ postcss: false,
24
+ minified: false,
25
+ },
26
+ };
27
+ const outputDir = path.resolve(__dirname, '../dist-tt');
28
+ if (!fs.existsSync(outputDir)) {
29
+ fs.mkdirSync(outputDir, { recursive: true });
30
+ }
31
+ fs.writeFileSync(
32
+ path.resolve(outputDir, 'project.config.json'),
33
+ JSON.stringify(config, null, 2),
34
+ );
35
+ };
36
+
16
37
  // https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数
17
38
  export default defineConfig<'vite'>(async (merge, _env) => {
18
- const isWeChatApp = process.env.TARO_ENV === 'weapp';
19
- const outputRoot = isWeChatApp ? 'dist' : 'dist-web';
39
+ const outputRootMap: Record<string, string> = {
40
+ weapp: 'dist-weapp',
41
+ tt: 'dist-tt',
42
+ h5: 'dist-web',
43
+ };
44
+ const outputRoot = outputRootMap[process.env.TARO_ENV || ''] || 'dist';
45
+ const isH5 = process.env.TARO_ENV === 'h5';
46
+
47
+ const buildMiniCIPluginConfig = () => {
48
+ const hasWeappConfig = !!process.env.TARO_APP_WEAPP_APPID;
49
+ const hasTTConfig = !!process.env.TARO_APP_TT_EMAIL;
50
+ if (!hasWeappConfig && !hasTTConfig) {
51
+ return [];
52
+ }
53
+ const miniCIConfig: Record<string, any> = {
54
+ version: pkg.version,
55
+ desc: pkg.description,
56
+ };
57
+ if (hasWeappConfig) {
58
+ miniCIConfig.weapp = {
59
+ appid: process.env.TARO_APP_WEAPP_APPID,
60
+ privateKeyPath: 'key/private.appid.key',
61
+ };
62
+ }
63
+ if (hasTTConfig) {
64
+ miniCIConfig.tt = {
65
+ email: process.env.TARO_APP_TT_EMAIL,
66
+ password: process.env.TARO_APP_TT_PASSWORD,
67
+ setting: {
68
+ skipDomainCheck: true,
69
+ },
70
+ };
71
+ }
72
+ return [['@tarojs/plugin-mini-ci', miniCIConfig]] as PluginItem[];
73
+ };
20
74
 
21
75
  const baseConfig: UserConfigExport<'vite'> = {
22
76
  projectName: '<%= appName %>',
@@ -33,24 +87,7 @@ export default defineConfig<'vite'>(async (merge, _env) => {
33
87
  },
34
88
  sourceRoot: 'src',
35
89
  outputRoot,
36
- plugins: [
37
- '@tarojs/plugin-generator',
38
- ...(process.env.TARO_APP_WEAPP_APPID
39
- ? ([
40
- [
41
- '@tarojs/plugin-mini-ci',
42
- {
43
- version: pkg.version,
44
- desc: pkg.description,
45
- weapp: {
46
- appid: process.env.TARO_APP_WEAPP_APPID,
47
- privateKeyPath: 'key/private.appid.key',
48
- },
49
- },
50
- ],
51
- ] as PluginItem[])
52
- : []),
53
- ],
90
+ plugins: ['@tarojs/plugin-generator', ...buildMiniCIPluginConfig()],
54
91
  defineConstants: {
55
92
  PROJECT_DOMAIN: JSON.stringify(
56
93
  process.env.PROJECT_DOMAIN ||
@@ -63,6 +100,13 @@ export default defineConfig<'vite'>(async (merge, _env) => {
63
100
  patterns: [],
64
101
  options: {},
65
102
  },
103
+ ...(process.env.TARO_ENV === 'tt' && {
104
+ tt: {
105
+ appid: process.env.TARO_APP_TT_APPID,
106
+ projectName: '<%= appName %>',
107
+ },
108
+ }),
109
+ jsMinimizer: 'esbuild',
66
110
  framework: 'react',
67
111
  compiler: {
68
112
  type: 'vite',
@@ -95,13 +139,24 @@ export default defineConfig<'vite'>(async (merge, _env) => {
95
139
  };
96
140
  },
97
141
  },
98
- UnifiedViteWeappTailwindcssPlugin({
99
- rem2rpx: true,
100
- cssEntries: [
101
- // 你 @import "tailwindcss"; 那个文件的绝对路径
102
- path.resolve(__dirname, '../src/app.css'),
103
- ],
104
- }),
142
+ ...(isH5
143
+ ? []
144
+ : [
145
+ UnifiedViteWeappTailwindcssPlugin({
146
+ rem2rpx: true,
147
+ cssEntries: [path.resolve(__dirname, '../src/app.css')],
148
+ }),
149
+ ]),
150
+ ...(process.env.TARO_ENV === 'tt'
151
+ ? [
152
+ {
153
+ name: 'generate-tt-project-config',
154
+ closeBundle() {
155
+ generateTTProjectConfig();
156
+ },
157
+ },
158
+ ]
159
+ : []),
105
160
  ],
106
161
  },
107
162
  mini: {
@@ -120,18 +175,21 @@ export default defineConfig<'vite'>(async (merge, _env) => {
120
175
  },
121
176
  },
122
177
  h5: {
123
- publicPath: '/',
178
+ publicPath: './',
124
179
  staticDirectory: 'static',
180
+ router: {
181
+ mode: 'hash',
182
+ },
125
183
  devServer: {
126
- port: <%= port %>,
127
- host: '0.0.0.0',
128
- open: false,
129
- proxy: {
130
- '/api': {
131
- target: 'http://localhost:<%= serverPort %>',
132
- changeOrigin: true,
133
- },
184
+ port: <%= port %>,
185
+ host: '0.0.0.0',
186
+ open: false,
187
+ proxy: {
188
+ '/api': {
189
+ target: 'http://localhost:<%= serverPort %>',
190
+ changeOrigin: true,
134
191
  },
192
+ },
135
193
  },
136
194
  miniCssExtractPluginOption: {
137
195
  ignoreOrder: true,
@@ -143,6 +201,12 @@ export default defineConfig<'vite'>(async (merge, _env) => {
143
201
  enable: true,
144
202
  config: {},
145
203
  },
204
+ pxtransform: {
205
+ enable: true,
206
+ config: {
207
+ platform: 'h5',
208
+ },
209
+ },
146
210
  cssModules: {
147
211
  enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
148
212
  config: {
@@ -1,10 +1,9 @@
1
- import type { UserConfigExport } from "@tarojs/cli"
1
+ import type { UserConfigExport } from '@tarojs/cli';
2
2
 
3
3
  export default {
4
4
  mini: {},
5
5
  h5: {
6
- // 确保产物为 es5
7
- legacy: true,
6
+ legacy: false,
8
7
  /**
9
8
  * WebpackChain 插件配置
10
9
  * @docs https://github.com/neutrinojs/webpack-chain
@@ -31,5 +30,5 @@ export default {
31
30
  // postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') })
32
31
  // }))
33
32
  // }
34
- }
35
- } satisfies UserConfigExport<'vite'>
33
+ },
34
+ } satisfies UserConfigExport<'vite'>;
@@ -16,6 +16,9 @@ export default [
16
16
  'react/jsx-uses-react': 'off',
17
17
  'react/react-in-jsx-scope': 'off',
18
18
  'jsx-quotes': ['error', 'prefer-double'],
19
+ 'react-hooks/exhaustive-deps': 'off',
20
+ 'tailwindcss/classnames-order': 'off',
21
+ 'tailwindcss/no-custom-classname': 'off',
19
22
  },
20
23
  },
21
24
  {
@@ -28,7 +31,66 @@ export default [
28
31
  selector:
29
32
  "MemberExpression[object.name='process'][property.name='env']",
30
33
  message:
31
- '请勿在 src 目录下直接使用 process.env\n如需获取 URL 请求前缀,请使用已经注入全局的 PROJECT_DOMAIN()',
34
+ '工程规范:请勿在 src 目录下直接使用 process.env\n如需获取 URL 请求前缀,请使用已经注入全局的 PROJECT_DOMAIN',
35
+ },
36
+ {
37
+ selector:
38
+ ":matches(ExportNamedDeclaration, ExportDefaultDeclaration) :matches([id.name='Network'], [declaration.id.name='Network'])",
39
+ message:
40
+ "工程规范:禁止自行定义 Network,项目已提供 src/network.ts,请直接使用: import { Network } from '@/network'",
41
+ },
42
+ {
43
+ selector:
44
+ 'Literal[value=/(^|\\s)(?:[^\\s:]+:)*(bg|text|border|divide|outline|ring|ring-offset|from|to|via|decoration|shadow|accent|caret|fill|stroke)-[a-z0-9-]+\\/([0-9]+|\\[[^\\]]+\\])/], TemplateElement[value.raw=/(^|\\s)(?:[^\\s:]+:)*(bg|text|border|divide|outline|ring|ring-offset|from|to|via|decoration|shadow|accent|caret|fill|stroke)-[a-z0-9-]+\\/([0-9]+|\\[[^\\]]+\\])/]',
45
+ message:
46
+ '微信小程序兼容性:禁用 Tailwind 颜色不透明度简写(如 bg-primary/10),该语法在微信小程序下 opacity 会丢失。请拆分写(如 bg-primary bg-opacity-10)。',
47
+ },
48
+ {
49
+ selector:
50
+ 'Literal[value=/(^|\\s)peer-[a-z0-9-]+\\b/], TemplateElement[value.raw=/(^|\\s)peer-[a-z0-9-]+\\b/]',
51
+ message:
52
+ '微信小程序兼容性:不支持 Tailwind 的 peer-*(如 peer-checked、peer-disabled)。',
53
+ },
54
+ {
55
+ selector:
56
+ 'Literal[value=/(^|\\s)group-[a-z0-9-]+\\b/], TemplateElement[value.raw=/(^|\\s)group-[a-z0-9-]+\\b/]',
57
+ message:
58
+ '微信小程序兼容性:不支持 Tailwind 的 group-*(如 group-hover)。',
59
+ },
60
+ {
61
+ selector:
62
+ 'Literal[value=/\\b(?!gap(?:-x|-y)?-)[a-zA-Z0-9-]+\\-[0-9]+\\.[0-9]+\\b/], TemplateElement[value.raw=/\\b(?!gap(?:-x|-y)?-)[a-zA-Z0-9-]+\\-[0-9]+\\.[0-9]+\\b/]',
63
+ message:
64
+ '微信小程序兼容性:禁用 Tailwind 小数值类名(如 space-y-1.5、w-0.5),请用整数替代(如 space-y-2、w-1)。',
65
+ },
66
+ {
67
+ selector:
68
+ ":matches(JSXAttribute[name.name='className'], CallExpression[callee.name=/^(cn|cva)$/]) :matches(Literal[value=/\\:has\\(/], TemplateElement[value.raw=/\\:has\\(/])",
69
+ message:
70
+ '微信小程序兼容性:WXSS 不支持 :has(...)(会导致预览上传失败)。',
71
+ },
72
+ {
73
+ selector:
74
+ ":matches(JSXAttribute[name.name='className'], CallExpression[callee.name=/^(cn|cva)$/]) :matches(Literal[value=/(^|\\s)has-[^\\s]+/], TemplateElement[value.raw=/(^|\\s)has-[^\\s]+/])",
75
+ message:
76
+ '微信小程序兼容性:禁用 Tailwind 的 has-* 变体(会生成 :has,导致预览上传失败)。',
77
+ },
78
+ {
79
+ selector:
80
+ ":matches(JSXAttribute[name.name='className'], CallExpression[callee.name=/^(cn|cva)$/]) :matches(Literal[value=/\\[&>\\*/], TemplateElement[value.raw=/\\[&>\\*/])",
81
+ message:
82
+ '微信小程序兼容性:禁用 [&>*...](可能生成非法 WXSS,如 >:last-child)。请改为 [&>view] 等明确标签。',
83
+ },
84
+ {
85
+ selector:
86
+ ":matches(JSXAttribute[name.name='className'], CallExpression[callee.name=/^(cn|cva)$/]) :matches(Literal[value=/\\[&[^\\]]*\\[data-/], TemplateElement[value.raw=/\\[&[^\\]]*\\[data-/])",
87
+ message:
88
+ '微信小程序兼容性:禁用 Tailwind 任意选择器里的属性选择器(如 [&>[data-...]]),可能导致预览上传失败。',
89
+ },
90
+ {
91
+ selector:
92
+ ":matches(JSXAttribute[name.name='className'], CallExpression[callee.name=/^(cn|cva)$/]) :matches(Literal[value=/\\[[^\\]]*&[^\\]]*~[^\\]]*\\]/], TemplateElement[value.raw=/\\[[^\\]]*&[^\\]]*~[^\\]]*\\]/])",
93
+ message: '微信小程序兼容性:WXSS 不支持 ~(会导致预览上传失败)。',
32
94
  },
33
95
  ],
34
96
  'no-restricted-properties': [
@@ -36,17 +98,33 @@ export default [
36
98
  {
37
99
  object: 'Taro',
38
100
  property: 'request',
39
- message: '请使用 Network.request 替代 Taro.request',
101
+ message:
102
+ "工程规范:请使用 Network.request 替代 Taro.request,导入方式: import { Network } from '@/network'",
40
103
  },
41
104
  {
42
105
  object: 'Taro',
43
106
  property: 'uploadFile',
44
- message: '请使用 Network.uploadFile 替代 Taro.uploadFile',
107
+ message:
108
+ "工程规范:请使用 Network.uploadFile 替代 Taro.uploadFile,导入方式: import { Network } from '@/network'",
45
109
  },
46
110
  {
47
111
  object: 'Taro',
48
112
  property: 'downloadFile',
49
- message: '请使用 Network.downloadFile 替代 Taro.downloadFile',
113
+ message:
114
+ "工程规范:请使用 Network.downloadFile 替代 Taro.downloadFile,导入方式: import { Network } from '@/network'",
115
+ },
116
+ ],
117
+ },
118
+ },
119
+ {
120
+ files: ['src/pages/index/index.tsx'],
121
+ rules: {
122
+ 'no-restricted-syntax': [
123
+ 'error',
124
+ {
125
+ selector: 'JSXText[value=/应用开发中/]',
126
+ message:
127
+ '工程规范:检测到首页 (src/pages/index/index) 仍为默认占位页面,这会导致用户无法进入新增页面,请根据用户需求开发实际的首页功能和界面。如果已经开发了新的首页,也需要删除旧首页,并更新 src/app.config.ts 文件',
50
128
  },
51
129
  ],
52
130
  },