@coze-arch/cli 0.0.1-alpha.e8683e → 0.0.1-alpha.e89608

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 (128) hide show
  1. package/README.md +1 -0
  2. package/lib/__templates__/expo/.cozeproj/scripts/dev_run.sh +25 -16
  3. package/lib/__templates__/expo/.cozeproj/scripts/server_dev_run.sh +9 -8
  4. package/lib/__templates__/expo/README.md +2 -2
  5. package/lib/__templates__/expo/client/app/+not-found.tsx +30 -0
  6. package/lib/__templates__/expo/client/app.config.ts +2 -2
  7. package/lib/__templates__/expo/client/components/Screen.tsx +2 -2
  8. package/lib/__templates__/expo/client/eslint.config.mjs +21 -1
  9. package/lib/__templates__/expo/client/hooks/useSafeRouter.ts +152 -0
  10. package/lib/__templates__/expo/client/metro.config.js +3 -0
  11. package/lib/__templates__/expo/client/package.json +36 -34
  12. package/lib/__templates__/expo/client/screens/demo/index.tsx +3 -3
  13. package/lib/__templates__/expo/client/scripts/install-missing-deps.js +10 -10
  14. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/index.js +9 -0
  15. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/rule.js +112 -0
  16. package/lib/__templates__/expo/eslint-plugins/forbid-emoji/tech.md +94 -0
  17. package/lib/__templates__/expo/eslint-plugins/react-native/index.js +9 -0
  18. package/lib/__templates__/expo/eslint-plugins/react-native/rule.js +64 -0
  19. package/lib/__templates__/expo/package.json +3 -0
  20. package/lib/__templates__/expo/patches/expo@54.0.33.patch +45 -0
  21. package/lib/__templates__/expo/pnpm-lock.yaml +1318 -2636
  22. package/lib/__templates__/expo/server/package.json +9 -7
  23. package/lib/__templates__/expo/server/src/index.ts +1 -0
  24. package/lib/__templates__/expo/template.config.js +56 -0
  25. package/lib/__templates__/native-static/.coze +11 -0
  26. package/lib/__templates__/native-static/index.html +33 -0
  27. package/lib/__templates__/native-static/styles/main.css +136 -0
  28. package/lib/__templates__/native-static/template.config.js +22 -0
  29. package/lib/__templates__/nextjs/README.md +5 -0
  30. package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
  31. package/lib/__templates__/nextjs/next.config.ts +1 -2
  32. package/lib/__templates__/nextjs/package.json +5 -6
  33. package/lib/__templates__/nextjs/pnpm-lock.yaml +2096 -956
  34. package/lib/__templates__/nextjs/scripts/build.sh +4 -1
  35. package/lib/__templates__/nextjs/scripts/dev.sh +1 -2
  36. package/lib/__templates__/nextjs/scripts/start.sh +1 -1
  37. package/lib/__templates__/nextjs/src/app/layout.tsx +1 -1
  38. package/lib/__templates__/nextjs/src/app/page.tsx +18 -60
  39. package/lib/__templates__/nextjs/src/server.ts +35 -0
  40. package/lib/__templates__/nextjs/template.config.js +49 -14
  41. package/lib/__templates__/nextjs/tsconfig.json +1 -1
  42. package/lib/__templates__/nuxt-vue/.coze +12 -0
  43. package/lib/__templates__/nuxt-vue/README.md +73 -0
  44. package/lib/__templates__/nuxt-vue/_gitignore +24 -0
  45. package/lib/__templates__/nuxt-vue/_npmrc +23 -0
  46. package/lib/__templates__/nuxt-vue/app/app.vue +6 -0
  47. package/lib/__templates__/nuxt-vue/app/pages/index.vue +23 -0
  48. package/lib/__templates__/nuxt-vue/assets/css/main.css +24 -0
  49. package/lib/__templates__/nuxt-vue/nuxt.config.ts +116 -0
  50. package/lib/__templates__/nuxt-vue/package.json +35 -0
  51. package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +8759 -0
  52. package/lib/__templates__/nuxt-vue/postcss.config.mjs +8 -0
  53. package/lib/__templates__/nuxt-vue/public/favicon.ico +0 -0
  54. package/lib/__templates__/nuxt-vue/public/robots.txt +2 -0
  55. package/lib/__templates__/nuxt-vue/scripts/build.sh +14 -0
  56. package/lib/__templates__/nuxt-vue/scripts/dev.sh +31 -0
  57. package/lib/__templates__/nuxt-vue/scripts/prepare.sh +14 -0
  58. package/lib/__templates__/nuxt-vue/scripts/start.sh +15 -0
  59. package/lib/__templates__/nuxt-vue/server/api/hello.ts +10 -0
  60. package/lib/__templates__/nuxt-vue/server/middleware/logger.ts +10 -0
  61. package/lib/__templates__/nuxt-vue/server/routes/health.ts +10 -0
  62. package/lib/__templates__/nuxt-vue/tailwind.config.js +13 -0
  63. package/lib/__templates__/nuxt-vue/template.config.js +87 -0
  64. package/lib/__templates__/nuxt-vue/tsconfig.json +18 -0
  65. package/lib/__templates__/taro/.coze +14 -0
  66. package/lib/__templates__/taro/.cozeproj/scripts/deploy_build.sh +19 -0
  67. package/lib/__templates__/taro/.cozeproj/scripts/deploy_run.sh +14 -0
  68. package/lib/__templates__/taro/.cozeproj/scripts/dev_build.sh +2 -0
  69. package/lib/__templates__/taro/.cozeproj/scripts/dev_run.sh +151 -0
  70. package/lib/__templates__/taro/.cozeproj/scripts/init_env.sh +5 -0
  71. package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +24 -0
  72. package/lib/__templates__/taro/README.md +751 -0
  73. package/lib/__templates__/taro/_gitignore +40 -0
  74. package/lib/__templates__/taro/_npmrc +18 -0
  75. package/lib/__templates__/taro/babel.config.js +12 -0
  76. package/lib/__templates__/taro/config/dev.ts +9 -0
  77. package/lib/__templates__/taro/config/index.ts +223 -0
  78. package/lib/__templates__/taro/config/prod.ts +34 -0
  79. package/lib/__templates__/taro/eslint.config.mjs +80 -0
  80. package/lib/__templates__/taro/key/private.appid.key +0 -0
  81. package/lib/__templates__/taro/package.json +107 -0
  82. package/lib/__templates__/taro/patches/@tarojs__plugin-mini-ci@4.1.9.patch +30 -0
  83. package/lib/__templates__/taro/pnpm-lock.yaml +23100 -0
  84. package/lib/__templates__/taro/pnpm-workspace.yaml +2 -0
  85. package/lib/__templates__/taro/project.config.json +15 -0
  86. package/lib/__templates__/taro/server/nest-cli.json +10 -0
  87. package/lib/__templates__/taro/server/package.json +40 -0
  88. package/lib/__templates__/taro/server/src/app.controller.ts +23 -0
  89. package/lib/__templates__/taro/server/src/app.module.ts +10 -0
  90. package/lib/__templates__/taro/server/src/app.service.ts +8 -0
  91. package/lib/__templates__/taro/server/src/interceptors/http-status.interceptor.ts +23 -0
  92. package/lib/__templates__/taro/server/src/main.ts +49 -0
  93. package/lib/__templates__/taro/server/tsconfig.json +24 -0
  94. package/lib/__templates__/taro/src/app.config.ts +11 -0
  95. package/lib/__templates__/taro/src/app.css +52 -0
  96. package/lib/__templates__/taro/src/app.tsx +9 -0
  97. package/lib/__templates__/taro/src/index.html +39 -0
  98. package/lib/__templates__/taro/src/network.ts +39 -0
  99. package/lib/__templates__/taro/src/pages/index/index.config.ts +3 -0
  100. package/lib/__templates__/taro/src/pages/index/index.css +1 -0
  101. package/lib/__templates__/taro/src/pages/index/index.tsx +33 -0
  102. package/lib/__templates__/taro/src/presets/dev-debug.ts +23 -0
  103. package/lib/__templates__/taro/src/presets/h5-container.tsx +15 -0
  104. package/lib/__templates__/taro/src/presets/h5-navbar.tsx +201 -0
  105. package/lib/__templates__/taro/src/presets/h5-styles.ts +142 -0
  106. package/lib/__templates__/taro/src/presets/index.tsx +18 -0
  107. package/lib/__templates__/taro/stylelint.config.mjs +4 -0
  108. package/lib/__templates__/taro/template.config.js +68 -0
  109. package/lib/__templates__/taro/tsconfig.json +29 -0
  110. package/lib/__templates__/taro/types/global.d.ts +32 -0
  111. package/lib/__templates__/templates.json +75 -0
  112. package/lib/__templates__/vite/README.md +189 -11
  113. package/lib/__templates__/vite/_gitignore +1 -0
  114. package/lib/__templates__/vite/eslint.config.mjs +6 -1
  115. package/lib/__templates__/vite/package.json +20 -3
  116. package/lib/__templates__/vite/pnpm-lock.yaml +944 -1551
  117. package/lib/__templates__/vite/scripts/build.sh +4 -1
  118. package/lib/__templates__/vite/scripts/dev.sh +2 -2
  119. package/lib/__templates__/vite/scripts/start.sh +3 -3
  120. package/lib/__templates__/vite/server/index.ts +57 -0
  121. package/lib/__templates__/vite/server/routes/index.ts +31 -0
  122. package/lib/__templates__/vite/server/vite.ts +79 -0
  123. package/lib/__templates__/vite/src/main.ts +17 -47
  124. package/lib/__templates__/vite/template.config.js +49 -14
  125. package/lib/__templates__/vite/tsconfig.json +4 -3
  126. package/lib/__templates__/vite/vite.config.ts +1 -0
  127. package/lib/cli.js +651 -173
  128. package/package.json +7 -3
@@ -0,0 +1,142 @@
1
+ /**
2
+ * H5 端特殊样式注入
3
+ * 如无必要,请勿修改本文件
4
+ */
5
+
6
+ const H5_BASE_STYLES = `
7
+ /* H5 端隐藏 TabBar 空图标(只隐藏没有 src 的图标) */
8
+ .weui-tabbar__icon:not([src]),
9
+ .weui-tabbar__icon[src=''] {
10
+ display: none !important;
11
+ }
12
+
13
+ .weui-tabbar__item:has(.weui-tabbar__icon:not([src])) .weui-tabbar__label,
14
+ .weui-tabbar__item:has(.weui-tabbar__icon[src='']) .weui-tabbar__label {
15
+ margin-top: 0 !important;
16
+ }
17
+
18
+ /* Vite 错误覆盖层无法选择文本的问题 */
19
+ vite-error-overlay {
20
+ /* stylelint-disable-next-line property-no-vendor-prefix */
21
+ -webkit-user-select: text !important;
22
+ }
23
+
24
+ vite-error-overlay::part(window) {
25
+ max-width: 90vw;
26
+ padding: 10px;
27
+ }
28
+
29
+ .taro_page {
30
+ overflow: auto;
31
+ }
32
+
33
+ ::-webkit-scrollbar {
34
+ width: 4px;
35
+ height: 4px;
36
+ }
37
+
38
+ ::-webkit-scrollbar-track {
39
+ background: transparent;
40
+ }
41
+
42
+ ::-webkit-scrollbar-thumb {
43
+ background: rgba(0, 0, 0, 0.2);
44
+ border-radius: 2px;
45
+ }
46
+
47
+ ::-webkit-scrollbar-thumb:hover {
48
+ background: rgba(0, 0, 0, 0.3);
49
+ }
50
+
51
+ /* H5 导航栏页面自动添加顶部间距 */
52
+ body.h5-navbar-visible .taro_page {
53
+ padding-top: 44px;
54
+ }
55
+ `;
56
+
57
+ const PC_WIDESCREEN_STYLES = `
58
+ /* PC 宽屏适配 - 基础布局 */
59
+ @media (min-width: 769px) {
60
+ html {
61
+ font-size: 15px !important;
62
+ }
63
+
64
+ body {
65
+ background-color: #f3f4f6 !important;
66
+ display: flex !important;
67
+ justify-content: center !important;
68
+ align-items: center !important;
69
+ min-height: 100vh !important;
70
+ }
71
+ }
72
+ `;
73
+
74
+ const PC_WIDESCREEN_PHONE_FRAME = `
75
+ /* PC 宽屏适配 - 手机框样式(有 TabBar 页面) */
76
+ @media (min-width: 769px) {
77
+ .taro-tabbar__container {
78
+ width: 375px !important;
79
+ max-width: 375px !important;
80
+ height: calc(100vh - 40px) !important;
81
+ max-height: 900px !important;
82
+ background-color: #fff !important;
83
+ transform: translateX(0) !important;
84
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.1) !important;
85
+ border-radius: 20px !important;
86
+ overflow: hidden !important;
87
+ position: relative !important;
88
+ }
89
+
90
+ .taro-tabbar__panel {
91
+ height: 100% !important;
92
+ overflow: auto !important;
93
+ }
94
+ }
95
+
96
+ /* PC 宽屏适配 - 手机框样式(无 TabBar 页面,通过 JS 添加 no-tabbar 类) */
97
+ @media (min-width: 769px) {
98
+ body.no-tabbar #app {
99
+ width: 375px !important;
100
+ max-width: 375px !important;
101
+ height: calc(100vh - 40px) !important;
102
+ max-height: 900px !important;
103
+ background-color: #fff !important;
104
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.1) !important;
105
+ border-radius: 20px !important;
106
+ overflow: hidden !important;
107
+ position: relative !important;
108
+ transform: translateX(0) !important;
109
+ }
110
+
111
+ body.no-tabbar #app .taro_router {
112
+ height: 100% !important;
113
+ overflow: auto !important;
114
+ }
115
+ }
116
+ `;
117
+
118
+ function injectStyles() {
119
+ const style = document.createElement('style');
120
+ style.innerHTML =
121
+ H5_BASE_STYLES + PC_WIDESCREEN_STYLES + PC_WIDESCREEN_PHONE_FRAME;
122
+ document.head.appendChild(style);
123
+ }
124
+
125
+ function setupTabbarDetection() {
126
+ const checkTabbar = () => {
127
+ const hasTabbar = !!document.querySelector('.taro-tabbar__container');
128
+ document.body.classList.toggle('no-tabbar', !hasTabbar);
129
+ };
130
+
131
+ checkTabbar();
132
+
133
+ const observer = new MutationObserver(checkTabbar);
134
+ observer.observe(document.body, { childList: true, subtree: true });
135
+ }
136
+
137
+ export function injectH5Styles() {
138
+ if (TARO_ENV !== 'h5') return;
139
+
140
+ injectStyles();
141
+ setupTabbarDetection();
142
+ }
@@ -0,0 +1,18 @@
1
+ import { useLaunch } from '@tarojs/taro';
2
+ import { PropsWithChildren } from 'react';
3
+ import { injectH5Styles } from './h5-styles';
4
+ import { devDebug } from './dev-debug';
5
+ import { H5Container } from './h5-container';
6
+
7
+ export const Preset = ({ children }: PropsWithChildren) => {
8
+ useLaunch(() => {
9
+ devDebug();
10
+ injectH5Styles();
11
+ });
12
+
13
+ if (TARO_ENV === 'h5') {
14
+ return <H5Container>{children}</H5Container>;
15
+ }
16
+
17
+ return <>{children}</>;
18
+ };
@@ -0,0 +1,4 @@
1
+ /** @type {import('stylelint').Config} */
2
+ export default {
3
+ extends: "stylelint-config-standard",
4
+ };
@@ -0,0 +1,68 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+ const description = `Taro(小程序 + H5):\`coze init \${COZE_WORKSPACE_PATH} --template taro\`
11
+ - 适用:微信小程序、H5 跨端应用
12
+ - 前后端分离架构:Taro 4 + NestJS
13
+ - 支持微信小程序和 H5 双端构建
14
+ - 使用 TailwindCSS + weapp-tailwindcss 实现跨端样式`;
15
+
16
+ export const paramsSchema = {
17
+ type: 'object',
18
+ properties: {
19
+ appName: {
20
+ type: 'string',
21
+ minLength: 1,
22
+ pattern: '^[a-z0-9-]+$',
23
+ description:
24
+ 'Application name (lowercase, alphanumeric and hyphens only)',
25
+ },
26
+ port: {
27
+ type: 'number',
28
+ default: 5000,
29
+ minimum: 1024,
30
+ maximum: 65535,
31
+ description: 'H5 development server port',
32
+ },
33
+ serverPort: {
34
+ type: 'number',
35
+ default: 3000,
36
+ minimum: 1024,
37
+ maximum: 65535,
38
+ description: 'NestJS backend server port',
39
+ },
40
+ },
41
+ required: [],
42
+ additionalProperties: false,
43
+ };
44
+
45
+ const config = {
46
+ description: description,
47
+ paramsSchema,
48
+ defaultParams: {
49
+ port: 5000,
50
+ serverPort: 3000,
51
+ appName: 'coze-mini-program',
52
+ },
53
+ onBeforeRender: async context => {
54
+ console.log(`Creating Taro project: ${context.appName}`);
55
+ return context;
56
+ },
57
+ onAfterRender: async (context, outputPath) => {
58
+ console.log(`\nProject created at: ${outputPath}`);
59
+ console.log('\nConfiguration:');
60
+ console.log(' - Framework: Taro 4 + NestJS');
61
+ console.log(' - TypeScript: enabled');
62
+ console.log(' - Platforms: H5, WeChat Mini Program');
63
+ console.log(` - H5 Port: ${context.port}`);
64
+ console.log(` - Server Port: ${context.serverPort}`);
65
+ },
66
+ };
67
+
68
+ export default config;
@@ -0,0 +1,29 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2017",
4
+ "module": "ESNext",
5
+ "removeComments": false,
6
+ "preserveConstEnums": true,
7
+ "moduleResolution": "bundler",
8
+ "experimentalDecorators": true,
9
+ "noImplicitAny": false,
10
+ "allowSyntheticDefaultImports": true,
11
+ "outDir": "lib",
12
+ "noUnusedLocals": true,
13
+ "noUnusedParameters": true,
14
+ "strictNullChecks": true,
15
+ "sourceMap": true,
16
+ "rootDir": ".",
17
+ "jsx": "react-jsx",
18
+ "allowJs": true,
19
+ "resolveJsonModule": true,
20
+ "typeRoots": [
21
+ "node_modules/@types"
22
+ ],
23
+ "paths": {
24
+ "@/*": ["./src/*"]
25
+ }
26
+ },
27
+ "include": ["./src", "./types", "./config"],
28
+ "compileOnSave": false
29
+ }
@@ -0,0 +1,32 @@
1
+ /// <reference types="@tarojs/taro" />
2
+
3
+ declare const PROJECT_DOMAIN: string | undefined;
4
+ declare const TARO_ENV: "weapp" | "h5" | undefined;
5
+
6
+ declare module '*.png';
7
+ declare module '*.gif';
8
+ declare module '*.jpg';
9
+ declare module '*.jpeg';
10
+ declare module '*.svg';
11
+ declare module '*.css';
12
+ declare module '*.less';
13
+ declare module '*.scss';
14
+ declare module '*.sass';
15
+ declare module '*.styl';
16
+
17
+ declare namespace NodeJS {
18
+ interface ProcessEnv {
19
+ /** NODE 内置环境变量, 会影响到最终构建生成产物 */
20
+ NODE_ENV: 'development' | 'production',
21
+ /** 当前构建的平台 */
22
+ TARO_ENV: 'weapp' | 'swan' | 'alipay' | 'h5' | 'rn' | 'tt' | 'qq' | 'jd' | 'harmony' | 'jdrn'
23
+ /**
24
+ * 当前构建的小程序 appid
25
+ * @description 若不同环境有不同的小程序,可通过在 env 文件中配置环境变量`TARO_APP_ID`来方便快速切换 appid, 而不必手动去修改 dist/project.config.json 文件
26
+ * @see https://taro-docs.jd.com/docs/next/env-mode-config#特殊环境变量-taro_app_id
27
+ */
28
+ TARO_APP_ID: string
29
+ }
30
+ }
31
+
32
+
@@ -26,6 +26,17 @@
26
26
  "additionalProperties": false
27
27
  }
28
28
  },
29
+ {
30
+ "name": "native-static",
31
+ "description": "Native Static(纯静态):`coze init ${COZE_WORKSPACE_PATH} --template native-static`\n- 适用:纯静态 HTML/CSS/JS 项目、静态网站\n- 使用 Python http.server 作为开发服务器\n- 不需要 Node.js 环境,适合简单静态内容",
32
+ "location": "./native-static",
33
+ "paramsSchema": {
34
+ "type": "object",
35
+ "properties": {},
36
+ "required": [],
37
+ "additionalProperties": false
38
+ }
39
+ },
29
40
  {
30
41
  "name": "nextjs",
31
42
  "description": "Next.js(复杂项目):`coze init ${COZE_WORKSPACE_PATH} --template nextjs`\n- 适用:全栈应用、复杂多页面等复杂项目\n- 使用默认nextjs项目规范\n - **目录规范**: 默认开启src目录(打开--src-dir选项):项目文件(如 app 目录、pages 目录、components 等)初始化到 src/ 目录下。\n - **项目理解加速**:初始可以依赖项目下 `package.json` 文件理解项目类型,如果没有或无法理解退化成阅读其他文件。\n - **UI设计与组件规范**:Next.js项目**必须默认**采用 shadcn/ui 风格和规范,`shadcn/ui`组件默认完整的预装在`src/components/ui/`目录下",
@@ -51,6 +62,70 @@
51
62
  "additionalProperties": false
52
63
  }
53
64
  },
65
+ {
66
+ "name": "nuxt-vue",
67
+ "description": "Nuxt.js(服务端 + Vue):`coze init ${COZE_WORKSPACE_PATH} --template nuxt-vue`\n- 适用:全栈应用、需要服务端接口能力的 Vue 项目\n- 特点:\n - **服务端能力**:内置服务端 API 路由,可直接创建后端接口\n - **Vue 3**:基于最新的 Vue 3 Composition API\n - **Vite**:使用 Vite 作为构建工具,开发体验极佳\n - **TypeScript**:完整的 TypeScript 支持\n - **文件路由**:基于文件系统的自动路由\n - **项目理解加速**:可依赖项目下 `package.json` 和 `nuxt.config.ts` 理解项目配置",
68
+ "location": "./nuxt-vue",
69
+ "paramsSchema": {
70
+ "type": "object",
71
+ "properties": {
72
+ "appName": {
73
+ "type": "string",
74
+ "minLength": 1,
75
+ "pattern": "^[a-z0-9-]+$",
76
+ "description": "Application name (lowercase, alphanumeric and hyphens only)"
77
+ },
78
+ "port": {
79
+ "type": "number",
80
+ "default": 5000,
81
+ "minimum": 1024,
82
+ "maximum": 65535,
83
+ "description": "Development server port (for Nuxt dev server)"
84
+ },
85
+ "hmrPort": {
86
+ "type": "number",
87
+ "default": 6000,
88
+ "minimum": 1024,
89
+ "maximum": 65535,
90
+ "description": "Hot Module Replacement (HMR) port"
91
+ }
92
+ },
93
+ "required": [],
94
+ "additionalProperties": false
95
+ }
96
+ },
97
+ {
98
+ "name": "taro",
99
+ "description": "Taro(小程序 + H5):`coze init ${COZE_WORKSPACE_PATH} --template taro`\n- 适用:微信小程序、H5 跨端应用\n- 前后端分离架构:Taro 4 + NestJS\n- 支持微信小程序和 H5 双端构建\n- 使用 TailwindCSS + weapp-tailwindcss 实现跨端样式",
100
+ "location": "./taro",
101
+ "paramsSchema": {
102
+ "type": "object",
103
+ "properties": {
104
+ "appName": {
105
+ "type": "string",
106
+ "minLength": 1,
107
+ "pattern": "^[a-z0-9-]+$",
108
+ "description": "Application name (lowercase, alphanumeric and hyphens only)"
109
+ },
110
+ "port": {
111
+ "type": "number",
112
+ "default": 5000,
113
+ "minimum": 1024,
114
+ "maximum": 65535,
115
+ "description": "H5 development server port"
116
+ },
117
+ "serverPort": {
118
+ "type": "number",
119
+ "default": 3000,
120
+ "minimum": 1024,
121
+ "maximum": 65535,
122
+ "description": "NestJS backend server port"
123
+ }
124
+ },
125
+ "required": [],
126
+ "additionalProperties": false
127
+ }
128
+ },
54
129
  {
55
130
  "name": "vite",
56
131
  "description": "Vite(简单项目):`coze init ${COZE_WORKSPACE_PATH} --template vite`\n- 适用:轻量级 SPA、纯前端交互、仪表盘等轻量级项目。",
@@ -1,6 +1,12 @@
1
1
  # <%= appName %>
2
2
 
3
- 这是一个基于 TypeScript + Vite + Tailwind CSS 的轻量级 Web 应用项目,由扣子编程 CLI 创建。
3
+ 这是一个基于 Koa + Vite + TypeScript + Tailwind CSS 的全栈 Web 应用项目,由扣子编程 CLI 创建。
4
+
5
+ **核心特性:**
6
+ - 🚀 前端:Vite + TypeScript + Tailwind CSS
7
+ - 🔧 后端:Koa + TypeScript,提供 RESTful API
8
+ - 🔥 开发模式:Vite HMR + Koa API,单进程启动
9
+ - 📦 生产模式:Koa 静态服务 + API,高性能部署
4
10
 
5
11
  ## 快速开始
6
12
 
@@ -33,19 +39,147 @@ coze start
33
39
  ## 项目结构
34
40
 
35
41
  ```
36
- ├── index.html # HTML 入口文件
37
- ├── src/
38
- │ ├── index.ts # 应用入口(初始化)
39
- ├── main.ts # 主逻辑文件
40
- │ └── index.css # 全局样式(包含 Tailwind 指令)
41
- ├── vite.config.ts # Vite 配置
42
- ├── tailwind.config.ts # Tailwind CSS 配置
43
- └── tsconfig.json # TypeScript 配置
42
+ ├── server/ # 后端服务器目录
43
+ ├── index.ts # Koa 服务器入口
44
+ │ ├── routes/ # API 路由目录
45
+ │ └── index.ts # 路由定义
46
+ │ └── vite.ts # Vite 集成逻辑
47
+ ├── src/ # 前端源码目录
48
+ ├── index.ts # 前端应用入口(初始化)
49
+ │ ├── main.ts # 前端主逻辑文件
50
+ │ └── index.css # 全局样式(包含 Tailwind 指令)
51
+ ├── index.html # HTML 入口文件
52
+ ├── vite.config.ts # Vite 配置
53
+ ├── tailwind.config.ts # Tailwind CSS 配置
54
+ └── tsconfig.json # TypeScript 配置
44
55
  ```
45
56
 
57
+ **目录说明:**
58
+
59
+ - **`server/`** - 后端服务器代码
60
+ - `index.ts` - 服务器主入口,负责创建和启动 Koa 应用
61
+ - `routes/` - API 路由模块,支持按功能拆分路由
62
+ - `vite.ts` - Vite 开发服务器和静态文件服务集成
63
+
64
+ - **`src/`** - 前端应用代码
65
+ - 所有前端相关代码都在这里
66
+
67
+ **工作原理:**
68
+
69
+ - **开发模式** (`coze dev`):
70
+ - 运行 `server/index.ts` 启动 Koa 服务器
71
+ - Vite 以 middleware 模式集成到 Koa
72
+ - 前端支持 HMR(热模块替换)
73
+ - 后端 API 和前端在同一进程,端口 <%= port %>
74
+
75
+ - **生产模式** (`coze start`):
76
+ - `coze build` 构建前端 → `dist/` 目录
77
+ - `coze build` 构建后端 → `dist-server/index.js` (CommonJS 格式)
78
+ - 运行 `dist-server/index.js` 启动生产服务器
79
+ - Koa 服务静态文件 + API 路由
80
+ - 单一 Node.js 进程,轻量高效
81
+
46
82
  ## 核心开发规范
47
83
 
48
- ### 1. 样式开发
84
+ ### 1. 后端 API 开发
85
+
86
+ **添加新的 API 路由**
87
+
88
+ 在 `server/routes/index.ts` 中添加路由:
89
+
90
+ ```typescript
91
+ // GET 请求示例
92
+ router.get('/api/users', async (ctx) => {
93
+ ctx.body = {
94
+ users: [
95
+ { id: 1, name: 'Alice' },
96
+ { id: 2, name: 'Bob' },
97
+ ],
98
+ };
99
+ });
100
+
101
+ // POST 请求示例
102
+ router.post('/api/users', async (ctx) => {
103
+ const userData = ctx.request.body;
104
+ // 处理业务逻辑
105
+ ctx.body = {
106
+ success: true,
107
+ user: userData,
108
+ };
109
+ });
110
+
111
+ // 动态路由参数
112
+ router.get('/api/users/:id', async (ctx) => {
113
+ const userId = ctx.params.id;
114
+ ctx.body = {
115
+ id: userId,
116
+ name: 'User ' + userId,
117
+ };
118
+ });
119
+ ```
120
+
121
+ **拆分路由模块**(推荐)
122
+
123
+ 当路由变多时,可以按功能拆分:
124
+
125
+ ```typescript
126
+ // server/routes/users.ts
127
+ import Router from '@koa/router';
128
+
129
+ const router = new Router();
130
+
131
+ router.get('/api/users', async (ctx) => {
132
+ // 用户列表逻辑
133
+ });
134
+
135
+ router.post('/api/users', async (ctx) => {
136
+ // 创建用户逻辑
137
+ });
138
+
139
+ export default router;
140
+ ```
141
+
142
+ 然后在 `server/index.ts` 中注册:
143
+
144
+ ```typescript
145
+ import usersRouter from './routes/users';
146
+
147
+ // 注册路由
148
+ app.use(usersRouter.routes()).use(usersRouter.allowedMethods());
149
+ ```
150
+
151
+ **前端调用 API**
152
+
153
+ ```typescript
154
+ // GET 请求
155
+ async function getUsers() {
156
+ const response = await fetch('/api/users');
157
+ const data = await response.json();
158
+ console.log(data);
159
+ }
160
+
161
+ // POST 请求
162
+ async function createUser(name: string) {
163
+ const response = await fetch('/api/users', {
164
+ method: 'POST',
165
+ headers: {
166
+ 'Content-Type': 'application/json',
167
+ },
168
+ body: JSON.stringify({ name }),
169
+ });
170
+ const data = await response.json();
171
+ console.log(data);
172
+ }
173
+ ```
174
+
175
+ **API 最佳实践**
176
+
177
+ - ✅ 所有 API 路由以 `/api` 开头,避免与前端路由冲突
178
+ - ✅ 使用 RESTful 设计:GET 查询、POST 创建、PUT 更新、DELETE 删除
179
+ - ✅ 返回统一的响应格式:`{ success: boolean, data?: any, error?: string }`
180
+ - ✅ 添加错误处理和参数验证
181
+
182
+ ### 2. 样式开发
49
183
 
50
184
  **使用 Tailwind CSS**
51
185
 
@@ -219,17 +353,32 @@ console.log(apiUrl); // https://api.example.com
219
353
 
220
354
  ## 技术栈
221
355
 
222
- - **构建工具**: Vite 6.x
356
+ **前端:**
357
+ - **构建工具**: Vite 7.x
223
358
  - **语言**: TypeScript 5.x
224
359
  - **样式**: Tailwind CSS 3.x
360
+
361
+ **后端:**
362
+ - **框架**: Koa 2.x
363
+ - **路由**: @koa/router 13.x
364
+ - **中间件**: koa-bodyparser, koa-static
365
+
366
+ **工具:**
225
367
  - **包管理器**: pnpm 9+
368
+ - **运行时**: Node.js 18+
369
+ - **开发工具**: tsx (TypeScript 执行器)
226
370
 
227
371
  ## 参考文档
228
372
 
373
+ **前端:**
229
374
  - [Vite 官方文档](https://cn.vitejs.dev/)
230
375
  - [TypeScript 官方文档](https://www.typescriptlang.org/zh/docs/)
231
376
  - [Tailwind CSS 文档](https://tailwindcss.com/docs)
232
377
 
378
+ **后端:**
379
+ - [Koa 官方文档](https://koajs.com/)
380
+ - [Koa Router 文档](https://github.com/koajs/router)
381
+
233
382
  ## 重要提示
234
383
 
235
384
  1. **必须使用 pnpm** 作为包管理器
@@ -237,3 +386,32 @@ console.log(apiUrl); // https://api.example.com
237
386
  3. **使用 Tailwind CSS** 进行样式开发,支持响应式和暗色模式
238
387
  4. **环境变量必须以 `VITE_` 开头** 才能在客户端代码中访问
239
388
  5. **开发时使用 `coze dev`**,支持热更新和快速刷新
389
+ 6. **API 路由以 `/api` 开头**,避免与前端路由冲突
390
+ 7. **单进程架构**:开发和生产环境都是前后端在同一进程中运行
391
+
392
+ ## 常见问题
393
+
394
+ **Q: 如何分离前后端端口?**
395
+
396
+ 如果需要前后端分离部署,可以:
397
+ - 前端:使用 `npx vite` 单独启动(默认端口 5173)
398
+ - 后端:修改 `server.ts`,移除 Vite middleware,单独启动
399
+
400
+ **Q: 如何添加数据库?**
401
+
402
+ ```bash
403
+ # 安装数据库客户端(以 PostgreSQL 为例)
404
+ pnpm add pg
405
+ pnpm add -D @types/pg
406
+
407
+ # 在 server.ts 中使用
408
+ import { Pool } from 'pg';
409
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL });
410
+ ```
411
+
412
+ **Q: 如何部署?**
413
+
414
+ 1. 运行 `coze build` 构建前后端
415
+ 2. 将整个项目上传到服务器
416
+ 3. 运行 `pnpm install --prod`
417
+ 4. 运行 `coze start` 启动服务
@@ -5,6 +5,7 @@ node_modules/
5
5
 
6
6
  # Production build
7
7
  dist/
8
+ dist-server/
8
9
  build/
9
10
  out/
10
11
 
@@ -5,5 +5,10 @@ import { defineConfig, globalIgnores } from 'eslint/config';
5
5
  export default defineConfig([
6
6
  eslint.configs.recommended,
7
7
  ...tseslint.configs.recommended,
8
- globalIgnores(['dist/**', 'node_modules/**']),
8
+ globalIgnores([
9
+ 'dist/**',
10
+ 'dist-server/**',
11
+ 'node_modules/**',
12
+ 'scripts/**',
13
+ ]),
9
14
  ]);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "<%= appName %>",
3
3
  "version": "1.0.0",
4
- "description": "Vanilla TypeScript application with Vite (HTML + CSS + TS)",
4
+ "description": "Vanilla TypeScript application with Koa + Vite (HTML + CSS + TS + Node API)",
5
5
  "scripts": {
6
6
  "build": "bash ./scripts/build.sh",
7
7
  "dev": "bash ./scripts/dev.sh",
@@ -10,13 +10,29 @@
10
10
  "start": "bash ./scripts/start.sh",
11
11
  "ts-check": "tsc -p tsconfig.json"
12
12
  },
13
+ "dependencies": {
14
+ "@koa/router": "^12.0.1",
15
+ "@supabase/supabase-js": "2.95.3",
16
+ "dotenv": "^17.2.3",
17
+ "koa": "^2.15.3",
18
+ "koa-bodyparser": "^4.4.1",
19
+ "koa-static": "^5.0.0"
20
+ },
13
21
  "devDependencies": {
22
+ "@types/koa": "^2.15.0",
23
+ "@types/koa__router": "^12.0.4",
24
+ "@types/koa-bodyparser": "^4.3.12",
25
+ "@types/koa-static": "^4.0.4",
26
+ "@types/node": "^22.10.5",
14
27
  "autoprefixer": "^10.4.20",
15
- "coze-coding-dev-sdk": "^0.7.3",
28
+ "coze-coding-dev-sdk": "^0.7.16",
29
+ "esbuild": "^0.24.2",
16
30
  "eslint": "^9",
17
31
  "only-allow": "^1.2.2",
18
32
  "postcss": "^8.4.49",
19
33
  "tailwindcss": "^3.4.17",
34
+ "tsup": "^8.3.5",
35
+ "tsx": "^4.19.2",
20
36
  "typescript": "^5.6.0",
21
37
  "typescript-eslint": "^8",
22
38
  "vite": "^7.2.4"
@@ -27,7 +43,8 @@
27
43
  },
28
44
  "pnpm": {
29
45
  "overrides": {
30
- "esbuild": "^0.27.2"
46
+ "esbuild": "^0.27.2",
47
+ "is-generator-function": "1.0.10"
31
48
  }
32
49
  }
33
50
  }