@coze-arch/cli 0.0.1-alpha.fc5c04 → 0.0.1-alpha.ff3d06

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/_npmrc +1 -0
  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/scripts/install-missing-deps.js +10 -10
  6. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/index.js +9 -0
  7. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/rule.js +112 -0
  8. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/tech.md +94 -0
  9. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/index.js +9 -0
  10. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/rule.js +120 -0
  11. package/lib/__templates__/expo/eslint-plugins/restrict-linear-gradient/tech.md +58 -0
  12. package/lib/__templates__/nextjs/AGENTS.md +54 -0
  13. package/lib/__templates__/nextjs/README.md +5 -0
  14. package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
  15. package/lib/__templates__/nextjs/next.config.ts +1 -2
  16. package/lib/__templates__/nextjs/package.json +2 -5
  17. package/lib/__templates__/nextjs/pnpm-lock.yaml +1028 -5
  18. package/lib/__templates__/nextjs/scripts/build.sh +4 -1
  19. package/lib/__templates__/nextjs/scripts/dev.sh +8 -2
  20. package/lib/__templates__/nextjs/scripts/start.sh +7 -1
  21. package/lib/__templates__/nextjs/src/app/layout.tsx +1 -1
  22. package/lib/__templates__/nextjs/src/app/page.tsx +1 -2
  23. package/lib/__templates__/nextjs/src/server.ts +35 -0
  24. package/lib/__templates__/nextjs/tsconfig.json +1 -1
  25. package/lib/__templates__/nuxt-vue/AGENTS.md +42 -0
  26. package/lib/__templates__/nuxt-vue/README.md +73 -0
  27. package/lib/__templates__/nuxt-vue/_gitignore +24 -0
  28. package/lib/__templates__/nuxt-vue/app/app.vue +6 -0
  29. package/lib/__templates__/nuxt-vue/app/pages/index.vue +23 -0
  30. package/lib/__templates__/{vite-vue/src/index.css → nuxt-vue/assets/css/main.css} +6 -11
  31. package/lib/__templates__/nuxt-vue/nuxt.config.ts +116 -0
  32. package/lib/__templates__/nuxt-vue/package.json +35 -0
  33. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +8759 -0
  34. package/lib/__templates__/{vite-vue → nuxt-vue}/postcss.config.mjs +3 -1
  35. package/lib/__templates__/nuxt-vue/public/favicon.ico +0 -0
  36. package/lib/__templates__/nuxt-vue/public/robots.txt +2 -0
  37. package/lib/__templates__/{vite-vue → nuxt-vue}/scripts/build.sh +2 -2
  38. package/lib/__templates__/{vite-vue → nuxt-vue}/scripts/dev.sh +9 -2
  39. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +14 -0
  40. package/lib/__templates__/nuxt-vue/scripts/start.sh +21 -0
  41. package/lib/__templates__/nuxt-vue/server/api/hello.ts +10 -0
  42. package/lib/__templates__/nuxt-vue/server/middleware/logger.ts +10 -0
  43. package/lib/__templates__/nuxt-vue/server/routes/health.ts +10 -0
  44. package/lib/__templates__/nuxt-vue/tailwind.config.js +13 -0
  45. package/lib/__templates__/nuxt-vue/template.config.js +87 -0
  46. package/lib/__templates__/nuxt-vue/tsconfig.json +18 -0
  47. package/lib/__templates__/taro/README.md +57 -45
  48. package/lib/__templates__/taro/config/index.ts +45 -30
  49. package/lib/__templates__/taro/eslint.config.mjs +61 -6
  50. package/lib/__templates__/taro/package.json +8 -3
  51. package/lib/__templates__/taro/pnpm-lock.yaml +515 -203
  52. package/lib/__templates__/taro/src/app.css +140 -36
  53. package/lib/__templates__/taro/src/components/ui/accordion.tsx +159 -0
  54. package/lib/__templates__/taro/src/components/ui/alert-dialog.tsx +260 -0
  55. package/lib/__templates__/taro/src/components/ui/alert.tsx +60 -0
  56. package/lib/__templates__/taro/src/components/ui/aspect-ratio.tsx +36 -0
  57. package/lib/__templates__/taro/src/components/ui/avatar.tsx +84 -0
  58. package/lib/__templates__/taro/src/components/ui/badge.tsx +37 -0
  59. package/lib/__templates__/taro/src/components/ui/breadcrumb.tsx +117 -0
  60. package/lib/__templates__/taro/src/components/ui/button-group.tsx +83 -0
  61. package/lib/__templates__/taro/src/components/ui/button.tsx +67 -0
  62. package/lib/__templates__/taro/src/components/ui/calendar.tsx +394 -0
  63. package/lib/__templates__/taro/src/components/ui/card.tsx +108 -0
  64. package/lib/__templates__/taro/src/components/ui/carousel.tsx +228 -0
  65. package/lib/__templates__/taro/src/components/ui/checkbox.tsx +58 -0
  66. package/lib/__templates__/taro/src/components/ui/code-block.tsx +169 -0
  67. package/lib/__templates__/taro/src/components/ui/collapsible.tsx +71 -0
  68. package/lib/__templates__/taro/src/components/ui/command.tsx +385 -0
  69. package/lib/__templates__/taro/src/components/ui/context-menu.tsx +614 -0
  70. package/lib/__templates__/taro/src/components/ui/dialog.tsx +256 -0
  71. package/lib/__templates__/taro/src/components/ui/drawer.tsx +192 -0
  72. package/lib/__templates__/taro/src/components/ui/dropdown-menu.tsx +561 -0
  73. package/lib/__templates__/taro/src/components/ui/field.tsx +228 -0
  74. package/lib/__templates__/taro/src/components/ui/hover-card.tsx +282 -0
  75. package/lib/__templates__/taro/src/components/ui/input-group.tsx +197 -0
  76. package/lib/__templates__/taro/src/components/ui/input-otp.tsx +136 -0
  77. package/lib/__templates__/taro/src/components/ui/input.tsx +56 -0
  78. package/lib/__templates__/taro/src/components/ui/label.tsx +24 -0
  79. package/lib/__templates__/taro/src/components/ui/menubar.tsx +595 -0
  80. package/lib/__templates__/taro/src/components/ui/navigation-menu.tsx +264 -0
  81. package/lib/__templates__/taro/src/components/ui/pagination.tsx +118 -0
  82. package/lib/__templates__/taro/src/components/ui/popover.tsx +291 -0
  83. package/lib/__templates__/taro/src/components/ui/portal.tsx +19 -0
  84. package/lib/__templates__/taro/src/components/ui/progress.tsx +28 -0
  85. package/lib/__templates__/taro/src/components/ui/radio-group.tsx +64 -0
  86. package/lib/__templates__/taro/src/components/ui/resizable.tsx +346 -0
  87. package/lib/__templates__/taro/src/components/ui/scroll-area.tsx +34 -0
  88. package/lib/__templates__/taro/src/components/ui/select.tsx +438 -0
  89. package/lib/__templates__/taro/src/components/ui/separator.tsx +30 -0
  90. package/lib/__templates__/taro/src/components/ui/sheet.tsx +262 -0
  91. package/lib/__templates__/taro/src/components/ui/skeleton.tsx +17 -0
  92. package/lib/__templates__/taro/src/components/ui/slider.tsx +203 -0
  93. package/lib/__templates__/taro/src/components/ui/sonner.tsx +1 -0
  94. package/lib/__templates__/taro/src/components/ui/switch.tsx +55 -0
  95. package/lib/__templates__/taro/src/components/ui/table.tsx +142 -0
  96. package/lib/__templates__/taro/src/components/ui/tabs.tsx +114 -0
  97. package/lib/__templates__/taro/src/components/ui/textarea.tsx +54 -0
  98. package/lib/__templates__/taro/src/components/ui/toast.tsx +517 -0
  99. package/lib/__templates__/taro/src/components/ui/toggle-group.tsx +120 -0
  100. package/lib/__templates__/taro/src/components/ui/toggle.tsx +77 -0
  101. package/lib/__templates__/taro/src/components/ui/tooltip.tsx +455 -0
  102. package/lib/__templates__/taro/src/lib/hooks/use-keyboard-offset.ts +37 -0
  103. package/lib/__templates__/taro/src/lib/measure.ts +115 -0
  104. package/lib/__templates__/taro/src/lib/platform.ts +12 -0
  105. package/lib/__templates__/taro/src/lib/utils.ts +6 -0
  106. package/lib/__templates__/taro/src/presets/h5-navbar.tsx +49 -12
  107. package/lib/__templates__/taro/src/presets/h5-styles.ts +78 -0
  108. package/lib/__templates__/templates.json +17 -17
  109. package/lib/__templates__/vite/AGENTS.md +41 -0
  110. package/lib/__templates__/vite/README.md +190 -11
  111. package/lib/__templates__/vite/_gitignore +1 -0
  112. package/lib/__templates__/vite/eslint.config.mjs +6 -1
  113. package/lib/__templates__/vite/package.json +10 -3
  114. package/lib/__templates__/vite/pnpm-lock.yaml +755 -15
  115. package/lib/__templates__/vite/scripts/build.sh +4 -1
  116. package/lib/__templates__/vite/scripts/dev.sh +9 -2
  117. package/lib/__templates__/vite/scripts/start.sh +9 -3
  118. package/lib/__templates__/vite/server/routes/index.ts +31 -0
  119. package/lib/__templates__/vite/server/server.ts +65 -0
  120. package/lib/__templates__/vite/server/vite.ts +67 -0
  121. package/lib/__templates__/vite/tsconfig.json +4 -3
  122. package/lib/__templates__/vite/vite.config.ts +4 -0
  123. package/lib/cli.js +3251 -768
  124. package/package.json +9 -3
  125. package/lib/__templates__/vite-vue/README.md +0 -451
  126. package/lib/__templates__/vite-vue/_gitignore +0 -66
  127. package/lib/__templates__/vite-vue/eslint.config.mjs +0 -9
  128. package/lib/__templates__/vite-vue/index.html +0 -13
  129. package/lib/__templates__/vite-vue/package.json +0 -38
  130. package/lib/__templates__/vite-vue/pnpm-lock.yaml +0 -3132
  131. package/lib/__templates__/vite-vue/scripts/prepare.sh +0 -9
  132. package/lib/__templates__/vite-vue/scripts/start.sh +0 -15
  133. package/lib/__templates__/vite-vue/src/App.vue +0 -6
  134. package/lib/__templates__/vite-vue/src/main.ts +0 -8
  135. package/lib/__templates__/vite-vue/src/router/index.ts +0 -17
  136. package/lib/__templates__/vite-vue/src/views/Home.vue +0 -38
  137. package/lib/__templates__/vite-vue/src/vite-env.d.ts +0 -8
  138. package/lib/__templates__/vite-vue/tailwind.config.js +0 -9
  139. package/lib/__templates__/vite-vue/template.config.js +0 -127
  140. package/lib/__templates__/vite-vue/tsconfig.json +0 -17
  141. package/lib/__templates__/vite-vue/vite.config.ts +0 -28
  142. /package/lib/__templates__/{vite-vue → nuxt-vue}/.coze +0 -0
  143. /package/lib/__templates__/{vite-vue → nuxt-vue}/_npmrc +0 -0
@@ -1,6 +1,8 @@
1
- export default {
1
+ const config = {
2
2
  plugins: {
3
3
  tailwindcss: {},
4
4
  autoprefixer: {},
5
5
  },
6
6
  };
7
+
8
+ export default config;
@@ -0,0 +1,2 @@
1
+ User-Agent: *
2
+ Disallow:
@@ -8,7 +8,7 @@ cd "${COZE_WORKSPACE_PATH}"
8
8
  echo "Installing dependencies..."
9
9
  pnpm install --prefer-frozen-lockfile --prefer-offline --loglevel debug --reporter=append-only
10
10
 
11
- echo "Building the project..."
12
- npx vite build
11
+ echo "Building the Nuxt.js project..."
12
+ npx nuxt build
13
13
 
14
14
  echo "Build completed successfully!"
@@ -1,9 +1,16 @@
1
1
  #!/bin/bash
2
2
  set -Eeuo pipefail
3
3
 
4
+ <% if (process.env.NODE_ENV === 'test') { %>
5
+ # 测试环境:支持环境变量覆盖端口
6
+ PORT="${PORT:-<%= port %>}"
7
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
8
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
9
+ <% } else { %>
4
10
  PORT=<%= port %>
5
11
  COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
6
12
  DEPLOY_RUN_PORT=<%= port %>
13
+ <% } %>
7
14
 
8
15
  cd "${COZE_WORKSPACE_PATH}"
9
16
 
@@ -27,6 +34,6 @@ kill_port_if_listening() {
27
34
 
28
35
  echo "Clearing port ${PORT} before start."
29
36
  kill_port_if_listening
30
- echo "Starting HTTP service on port ${PORT} for dev..."
37
+ echo "Starting Nuxt dev server on port ${PORT}..."
31
38
 
32
- npx vite --port $PORT
39
+ PORT=$PORT npx nuxt dev
@@ -0,0 +1,14 @@
1
+ #!/bin/bash
2
+ set -Eeuo pipefail
3
+
4
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
5
+
6
+ cd "${COZE_WORKSPACE_PATH}"
7
+
8
+ echo "Installing dependencies..."
9
+ pnpm install --prefer-frozen-lockfile --prefer-offline
10
+
11
+ echo "Preparing Nuxt project..."
12
+ pnpm exec nuxt prepare
13
+
14
+ echo "Preparation completed successfully!"
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ set -Eeuo pipefail
3
+
4
+ COZE_WORKSPACE_PATH="${COZE_WORKSPACE_PATH:-$(pwd)}"
5
+ <% if (process.env.NODE_ENV === 'test') { %>
6
+ # 测试环境:支持环境变量覆盖端口
7
+ PORT="${PORT:-<%= port %>}"
8
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-${PORT}}"
9
+ <% } else { %>
10
+ PORT=<%= port %>
11
+ DEPLOY_RUN_PORT="${DEPLOY_RUN_PORT:-$PORT}"
12
+ <% } %>
13
+
14
+ start_service() {
15
+ cd "${COZE_WORKSPACE_PATH}"
16
+ echo "Starting Nuxt.js service on port ${DEPLOY_RUN_PORT} for production..."
17
+ PORT=${DEPLOY_RUN_PORT} node .output/server/index.mjs
18
+ }
19
+
20
+ echo "Starting Nuxt.js service on port ${DEPLOY_RUN_PORT} for production..."
21
+ start_service
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hello API 示例
3
+ * 访问: http://localhost:<%= port %>/api/hello
4
+ */
5
+ export default defineEventHandler(() => {
6
+ return {
7
+ message: 'Hello from Nuxt API',
8
+ timestamp: new Date().toISOString(),
9
+ };
10
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 请求日志中间件(仅开发环境)
3
+ */
4
+ export default defineEventHandler((event) => {
5
+ const isDev = process.env.COZE_PROJECT_ENV !== 'PROD';
6
+
7
+ if (isDev) {
8
+ console.log(`${event.method} ${event.path}`);
9
+ }
10
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 健康检查路由
3
+ * 访问: http://localhost:<%= port %>/health
4
+ */
5
+ export default defineEventHandler(() => {
6
+ return {
7
+ status: 'ok',
8
+ timestamp: new Date().toISOString(),
9
+ };
10
+ });
@@ -0,0 +1,13 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: [
4
+ './app/**/*.{js,ts,jsx,tsx,vue}',
5
+ './pages/**/*.{js,ts,jsx,tsx,vue}',
6
+ './components/**/*.{js,ts,jsx,tsx,vue}',
7
+ ],
8
+ darkMode: 'media',
9
+ theme: {
10
+ extend: {},
11
+ },
12
+ plugins: [],
13
+ };
@@ -0,0 +1,87 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+ const description = `Nuxt.js(服务端 + Vue):\`coze init \${COZE_WORKSPACE_PATH} --template nuxt-vue\`
11
+ - 适用:全栈应用、需要服务端接口能力的 Vue 项目
12
+ - 特点:
13
+ - **服务端能力**:内置服务端 API 路由,可直接创建后端接口
14
+ - **Vue 3**:基于最新的 Vue 3 Composition API
15
+ - **Vite**:使用 Vite 作为构建工具,开发体验极佳
16
+ - **TypeScript**:完整的 TypeScript 支持
17
+ - **文件路由**:基于文件系统的自动路由
18
+ - **项目理解加速**:可依赖项目下 \`package.json\` 和 \`nuxt.config.ts\` 理解项目配置`;
19
+
20
+ export const paramsSchema = {
21
+ type: 'object',
22
+ properties: {
23
+ appName: {
24
+ type: 'string',
25
+ minLength: 1,
26
+ pattern: '^[a-z0-9-]+$',
27
+ description:
28
+ 'Application name (lowercase, alphanumeric and hyphens only)',
29
+ },
30
+ port: {
31
+ type: 'number',
32
+ default: 5000,
33
+ minimum: 1024,
34
+ maximum: 65535,
35
+ description: 'Development server port (for Nuxt dev server)',
36
+ },
37
+ hmrPort: {
38
+ type: 'number',
39
+ default: 6000,
40
+ minimum: 1024,
41
+ maximum: 65535,
42
+ description: 'Hot Module Replacement (HMR) port',
43
+ },
44
+ },
45
+ required: [],
46
+ additionalProperties: false,
47
+ };
48
+
49
+ const config = {
50
+ description: description,
51
+ paramsSchema,
52
+
53
+ // 显式定义默认参数,确保在渲染时可用
54
+ defaultParams: {
55
+ port: 5000,
56
+ hmrPort: 6000,
57
+ appName: 'nuxt-vue',
58
+ },
59
+
60
+ onBeforeRender: async context => {
61
+ console.log(`Creating Nuxt.js project: ${context.appName}`);
62
+ return context;
63
+ },
64
+
65
+ onAfterRender: async (_context, outputPath) => {
66
+ console.log(`\nProject created at: ${outputPath}`);
67
+ console.log('\nConfiguration:');
68
+ console.log(' - Framework: Nuxt.js');
69
+ console.log(' - TypeScript: enabled');
70
+ console.log(' - Vue: 3.x');
71
+ console.log(' - Build Tool: Vite');
72
+ console.log(` - Port: ${_context.port}`);
73
+ },
74
+
75
+ onComplete: async (_context, _outputPath) => {
76
+ // Skip additional setup in test environment
77
+ if (process.env.NODE_ENV === 'test') {
78
+ console.log('⊘ Skipping additional setup in test environment');
79
+ return;
80
+ }
81
+
82
+ console.log('\n✓ Nuxt.js project setup completed!');
83
+ console.log(' You can now start the development server');
84
+ },
85
+ };
86
+
87
+ export default config;
@@ -0,0 +1,18 @@
1
+ {
2
+ // https://nuxt.com/docs/guide/concepts/typescript
3
+ "files": [],
4
+ "references": [
5
+ {
6
+ "path": "./.nuxt/tsconfig.app.json"
7
+ },
8
+ {
9
+ "path": "./.nuxt/tsconfig.server.json"
10
+ },
11
+ {
12
+ "path": "./.nuxt/tsconfig.shared.json"
13
+ },
14
+ {
15
+ "path": "./.nuxt/tsconfig.node.json"
16
+ }
17
+ ]
18
+ }
@@ -105,56 +105,39 @@ pnpm preview:weapp # 构建并生成预览小程序二维码
105
105
  pnpm new # 交互式创建页面/组件
106
106
  ```
107
107
 
108
- ### 常用 Taro 组件
108
+ ### 组件库
109
109
 
110
- 引入方式
110
+ #### UI 组件
111
+
112
+ UI 组件位于 `@/components/ui`,推荐按需引入:
113
+
114
+ ```typescript
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 未覆盖)
111
126
 
112
127
  ```typescript
113
- import { Text } from '@tarojs/components'
114
- ```
115
- - 基础组件
116
- - Text
117
- - Icon
118
- - Progress
119
- - RichText
120
- - 表单组件
121
- - Button
122
- - Checkbox
123
- - CheckboxGroup
124
- - Editor
125
- - Form
126
- - Input
127
- - Label
128
- - Picker
129
- - PickerView
130
- - PickerViewColumn
131
- - Radio
132
- - RadioGroup
133
- - Slider
134
- - Switch
135
- - Textarea
136
- - 导航组件
137
- - FunctionalPageNavigator
138
- - NavigationBar
139
- - Navigator
140
- - TabItem
141
- - Tabs
142
- - 媒体组件
143
- - Camera
144
- - Image
145
- - Video
146
- - 视图容器
147
- - ScrollView
148
- - Swiper
149
- - SwiperItem
150
- - View
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
151
134
 
152
135
  ### 路径别名
153
136
 
154
137
  项目配置了 `@/*` 路径别名指向 `src/*`:
155
138
 
156
139
  ```typescript
157
- import { SomeComponent } from '@/components/SomeComponent'
140
+ import { SomeComponent } from '@/components/some-component'
158
141
  import { useUserStore } from '@/stores/user'
159
142
  ```
160
143
 
@@ -164,9 +147,18 @@ import { useUserStore } from '@/stores/user'
164
147
 
165
148
  ```tsx
166
149
  // src/pages/example/index.tsx
167
- import { View, Text } from '@tarojs/components'
150
+ import { View } from '@tarojs/components'
168
151
  import { useLoad, useDidShow } from '@tarojs/taro'
169
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'
170
162
  import './index.css'
171
163
 
172
164
  const ExamplePage: FC = () => {
@@ -179,8 +171,25 @@ const ExamplePage: FC = () => {
179
171
  })
180
172
 
181
173
  return (
182
- <View className="flex flex-col items-center p-4">
183
- <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>
184
193
  </View>
185
194
  )
186
195
  }
@@ -445,10 +454,13 @@ IMPORTANT:必须使用 tailwindcss 实现样式,只有在必要情况下才
445
454
  > 项目已集成 Tailwind CSS 4.x + weapp-tailwindcss,支持跨端原子化样式:
446
455
 
447
456
  ```tsx
457
+ import { View, Text } from '@tarojs/components'
458
+ import { Button } from '@/components/ui/button'
459
+
448
460
  <View className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
449
461
  <Text className="text-2xl font-bold text-blue-600 mb-4">标题</Text>
450
462
  <View className="w-full px-4">
451
- <Button className="w-full bg-blue-500 text-white rounded-lg py-3">
463
+ <Button className="w-full" size="lg">
452
464
  按钮
453
465
  </Button>
454
466
  </View>
@@ -12,7 +12,7 @@ import pkg from '../package.json';
12
12
 
13
13
  dotenv.config({ path: path.resolve(__dirname, '../.env.local') });
14
14
 
15
- const generateTTProjectConfig = () => {
15
+ const generateTTProjectConfig = (outputRoot: string) => {
16
16
  const config = {
17
17
  miniprogramRoot: './',
18
18
  projectname: '<%= appName %>',
@@ -24,7 +24,7 @@ const generateTTProjectConfig = () => {
24
24
  minified: false,
25
25
  },
26
26
  };
27
- const outputDir = path.resolve(__dirname, '../dist-tt');
27
+ const outputDir = path.resolve(__dirname, '..', outputRoot);
28
28
  if (!fs.existsSync(outputDir)) {
29
29
  fs.mkdirSync(outputDir, { recursive: true });
30
30
  }
@@ -37,39 +37,41 @@ const generateTTProjectConfig = () => {
37
37
  // https://taro-docs.jd.com/docs/next/config#defineconfig-辅助函数
38
38
  export default defineConfig<'vite'>(async (merge, _env) => {
39
39
  const outputRootMap: Record<string, string> = {
40
- weapp: 'dist',
40
+ weapp: 'dist-weapp',
41
41
  tt: 'dist-tt',
42
42
  h5: 'dist-web',
43
43
  };
44
- const outputRoot = outputRootMap[process.env.TARO_ENV || ''] || 'dist-web';
44
+ const defaultOutputRoot = outputRootMap[process.env.TARO_ENV || ''] || 'dist';
45
+ const outputRoot = process.env.OUTPUT_ROOT?.trim() || defaultOutputRoot;
46
+ const isH5 = process.env.TARO_ENV === 'h5';
45
47
 
46
48
  const buildMiniCIPluginConfig = () => {
47
- const hasWeappConfig = !!process.env.TARO_APP_WEAPP_APPID
48
- const hasTTConfig = !!process.env.TARO_APP_TT_EMAIL
49
+ const hasWeappConfig = !!process.env.TARO_APP_WEAPP_APPID;
50
+ const hasTTConfig = !!process.env.TARO_APP_TT_EMAIL;
49
51
  if (!hasWeappConfig && !hasTTConfig) {
50
- return []
52
+ return [];
51
53
  }
52
54
  const miniCIConfig: Record<string, any> = {
53
- version: pkg.version,
54
- desc: pkg.description,
55
- }
55
+ version: pkg.version,
56
+ desc: pkg.description,
57
+ };
56
58
  if (hasWeappConfig) {
57
- miniCIConfig.weapp = {
58
- appid: process.env.TARO_APP_WEAPP_APPID,
59
- privateKeyPath: 'key/private.appid.key',
60
- }
59
+ miniCIConfig.weapp = {
60
+ appid: process.env.TARO_APP_WEAPP_APPID,
61
+ privateKeyPath: 'key/private.appid.key',
62
+ };
61
63
  }
62
64
  if (hasTTConfig) {
63
- miniCIConfig.tt = {
64
- email: process.env.TARO_APP_TT_EMAIL,
65
- password: process.env.TARO_APP_TT_PASSWORD,
66
- setting: {
67
- skipDomainCheck: true,
68
- },
69
- }
65
+ miniCIConfig.tt = {
66
+ email: process.env.TARO_APP_TT_EMAIL,
67
+ password: process.env.TARO_APP_TT_PASSWORD,
68
+ setting: {
69
+ skipDomainCheck: true,
70
+ },
71
+ };
70
72
  }
71
- return [['@tarojs/plugin-mini-ci', miniCIConfig]] as PluginItem[]
72
- }
73
+ return [['@tarojs/plugin-mini-ci', miniCIConfig]] as PluginItem[];
74
+ };
73
75
 
74
76
  const baseConfig: UserConfigExport<'vite'> = {
75
77
  projectName: '<%= appName %>',
@@ -86,7 +88,7 @@ export default defineConfig<'vite'>(async (merge, _env) => {
86
88
  },
87
89
  sourceRoot: 'src',
88
90
  outputRoot,
89
- plugins: ['@tarojs/plugin-generator', ...buildMiniCIPluginConfig()],
91
+ plugins: ['@tarojs/plugin-generator', ...buildMiniCIPluginConfig()],
90
92
  defineConstants: {
91
93
  PROJECT_DOMAIN: JSON.stringify(
92
94
  process.env.PROJECT_DOMAIN ||
@@ -138,16 +140,20 @@ export default defineConfig<'vite'>(async (merge, _env) => {
138
140
  };
139
141
  },
140
142
  },
141
- UnifiedViteWeappTailwindcssPlugin({
142
- rem2rpx: true,
143
- cssEntries: [path.resolve(__dirname, '../src/app.css')],
144
- }),
143
+ ...(isH5
144
+ ? []
145
+ : [
146
+ UnifiedViteWeappTailwindcssPlugin({
147
+ rem2rpx: true,
148
+ cssEntries: [path.resolve(__dirname, '../src/app.css')],
149
+ }),
150
+ ]),
145
151
  ...(process.env.TARO_ENV === 'tt'
146
152
  ? [
147
153
  {
148
154
  name: 'generate-tt-project-config',
149
155
  closeBundle() {
150
- generateTTProjectConfig();
156
+ generateTTProjectConfig(outputRoot);
151
157
  },
152
158
  },
153
159
  ]
@@ -170,8 +176,11 @@ export default defineConfig<'vite'>(async (merge, _env) => {
170
176
  },
171
177
  },
172
178
  h5: {
173
- publicPath: '/',
179
+ publicPath: './',
174
180
  staticDirectory: 'static',
181
+ router: {
182
+ mode: 'hash',
183
+ },
175
184
  devServer: {
176
185
  port: <%= port %>,
177
186
  host: '0.0.0.0',
@@ -193,6 +202,12 @@ export default defineConfig<'vite'>(async (merge, _env) => {
193
202
  enable: true,
194
203
  config: {},
195
204
  },
205
+ pxtransform: {
206
+ enable: true,
207
+ config: {
208
+ platform: 'h5',
209
+ },
210
+ },
196
211
  cssModules: {
197
212
  enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
198
213
  config: {
@@ -17,6 +17,8 @@ export default [
17
17
  'react/react-in-jsx-scope': 'off',
18
18
  'jsx-quotes': ['error', 'prefer-double'],
19
19
  'react-hooks/exhaustive-deps': 'off',
20
+ 'tailwindcss/classnames-order': 'off',
21
+ 'tailwindcss/no-custom-classname': 'off',
20
22
  },
21
23
  },
22
24
  {
@@ -29,13 +31,66 @@ export default [
29
31
  selector:
30
32
  "MemberExpression[object.name='process'][property.name='env']",
31
33
  message:
32
- '请勿在 src 目录下直接使用 process.env\n如需获取 URL 请求前缀,请使用已经注入全局的 PROJECT_DOMAIN',
34
+ '工程规范:请勿在 src 目录下直接使用 process.env\n如需获取 URL 请求前缀,请使用已经注入全局的 PROJECT_DOMAIN',
33
35
  },
34
36
  {
35
37
  selector:
36
38
  ":matches(ExportNamedDeclaration, ExportDefaultDeclaration) :matches([id.name='Network'], [declaration.id.name='Network'])",
37
39
  message:
38
- "禁止自行定义 Network,项目已提供 src/network.ts,请直接使用: import { Network } from '@/network'",
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 不支持 ~(会导致预览上传失败)。',
39
94
  },
40
95
  ],
41
96
  'no-restricted-properties': [
@@ -44,19 +99,19 @@ export default [
44
99
  object: 'Taro',
45
100
  property: 'request',
46
101
  message:
47
- "请使用 Network.request 替代 Taro.request,导入方式: import { Network } from '@/network'",
102
+ "工程规范:请使用 Network.request 替代 Taro.request,导入方式: import { Network } from '@/network'",
48
103
  },
49
104
  {
50
105
  object: 'Taro',
51
106
  property: 'uploadFile',
52
107
  message:
53
- "请使用 Network.uploadFile 替代 Taro.uploadFile,导入方式: import { Network } from '@/network'",
108
+ "工程规范:请使用 Network.uploadFile 替代 Taro.uploadFile,导入方式: import { Network } from '@/network'",
54
109
  },
55
110
  {
56
111
  object: 'Taro',
57
112
  property: 'downloadFile',
58
113
  message:
59
- "请使用 Network.downloadFile 替代 Taro.downloadFile,导入方式: import { Network } from '@/network'",
114
+ "工程规范:请使用 Network.downloadFile 替代 Taro.downloadFile,导入方式: import { Network } from '@/network'",
60
115
  },
61
116
  ],
62
117
  },
@@ -69,7 +124,7 @@ export default [
69
124
  {
70
125
  selector: 'JSXText[value=/应用开发中/]',
71
126
  message:
72
- '检测到首页 (src/pages/index/index) 仍为默认占位页面,这会导致用户无法进入新增页面,请根据用户需求开发实际的首页功能和界面。如果已经开发了新的首页,也需要删除旧首页,并更新 src/app.config.ts 文件',
127
+ '工程规范:检测到首页 (src/pages/index/index) 仍为默认占位页面,这会导致用户无法进入新增页面,请根据用户需求开发实际的首页功能和界面。如果已经开发了新的首页,也需要删除旧首页,并更新 src/app.config.ts 文件',
73
128
  },
74
129
  ],
75
130
  },