@coze-arch/cli 0.0.1-alpha.8a7e7e → 0.0.1-alpha.8b5326
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.
- package/README.md +1 -0
- package/lib/__templates__/expo/client/components/Screen.tsx +2 -2
- package/lib/__templates__/expo/client/eslint.config.mjs +4 -0
- package/lib/__templates__/expo/client/scripts/install-missing-deps.js +10 -10
- package/lib/__templates__/expo/eslint-plugins/forbid-emoji/index.js +9 -0
- package/lib/__templates__/expo/eslint-plugins/forbid-emoji/rule.js +112 -0
- package/lib/__templates__/expo/eslint-plugins/forbid-emoji/tech.md +94 -0
- package/lib/__templates__/nextjs/README.md +5 -0
- package/lib/__templates__/nextjs/eslint.config.mjs +5 -0
- package/lib/__templates__/nextjs/next.config.ts +1 -2
- package/lib/__templates__/nextjs/package.json +2 -5
- package/lib/__templates__/nextjs/pnpm-lock.yaml +1028 -5
- package/lib/__templates__/nextjs/scripts/build.sh +4 -1
- package/lib/__templates__/nextjs/scripts/dev.sh +8 -2
- package/lib/__templates__/nextjs/scripts/start.sh +7 -1
- package/lib/__templates__/nextjs/src/app/layout.tsx +1 -1
- package/lib/__templates__/nextjs/src/app/page.tsx +1 -2
- package/lib/__templates__/nextjs/src/server.ts +35 -0
- package/lib/__templates__/nextjs/tsconfig.json +1 -1
- package/lib/__templates__/nuxt-vue/README.md +73 -0
- package/lib/__templates__/nuxt-vue/_gitignore +24 -0
- package/lib/__templates__/nuxt-vue/app/app.vue +6 -0
- package/lib/__templates__/nuxt-vue/app/pages/index.vue +23 -0
- package/lib/__templates__/{vite-vue/src/index.css → nuxt-vue/assets/css/main.css} +6 -11
- package/lib/__templates__/nuxt-vue/nuxt.config.ts +116 -0
- package/lib/__templates__/nuxt-vue/package.json +35 -0
- package/lib/__templates__/nuxt-vue/pnpm-lock.yaml +8759 -0
- package/lib/__templates__/{vite-vue → nuxt-vue}/postcss.config.mjs +3 -1
- package/lib/__templates__/nuxt-vue/public/favicon.ico +0 -0
- package/lib/__templates__/nuxt-vue/public/robots.txt +2 -0
- package/lib/__templates__/{vite-vue → nuxt-vue}/scripts/build.sh +2 -2
- package/lib/__templates__/{vite-vue → nuxt-vue}/scripts/dev.sh +9 -2
- package/lib/__templates__/nuxt-vue/scripts/prepare.sh +14 -0
- package/lib/__templates__/nuxt-vue/scripts/start.sh +21 -0
- package/lib/__templates__/nuxt-vue/server/api/hello.ts +10 -0
- package/lib/__templates__/nuxt-vue/server/middleware/logger.ts +10 -0
- package/lib/__templates__/nuxt-vue/server/routes/health.ts +10 -0
- package/lib/__templates__/nuxt-vue/tailwind.config.js +13 -0
- package/lib/__templates__/nuxt-vue/template.config.js +87 -0
- package/lib/__templates__/nuxt-vue/tsconfig.json +18 -0
- package/lib/__templates__/templates.json +17 -17
- package/lib/__templates__/vite/README.md +190 -11
- package/lib/__templates__/vite/_gitignore +1 -0
- package/lib/__templates__/vite/eslint.config.mjs +6 -1
- package/lib/__templates__/vite/package.json +10 -3
- package/lib/__templates__/vite/pnpm-lock.yaml +755 -15
- package/lib/__templates__/vite/scripts/build.sh +4 -1
- package/lib/__templates__/vite/scripts/dev.sh +9 -2
- package/lib/__templates__/vite/scripts/start.sh +9 -3
- package/lib/__templates__/vite/server/routes/index.ts +31 -0
- package/lib/__templates__/vite/server/server.ts +65 -0
- package/lib/__templates__/vite/server/vite.ts +67 -0
- package/lib/__templates__/vite/tsconfig.json +4 -3
- package/lib/__templates__/vite/vite.config.ts +4 -0
- package/lib/cli.js +99 -92
- package/package.json +6 -3
- package/lib/__templates__/vite-vue/README.md +0 -451
- package/lib/__templates__/vite-vue/_gitignore +0 -66
- package/lib/__templates__/vite-vue/eslint.config.mjs +0 -9
- package/lib/__templates__/vite-vue/index.html +0 -13
- package/lib/__templates__/vite-vue/package.json +0 -38
- package/lib/__templates__/vite-vue/pnpm-lock.yaml +0 -3132
- package/lib/__templates__/vite-vue/scripts/prepare.sh +0 -9
- package/lib/__templates__/vite-vue/scripts/start.sh +0 -15
- package/lib/__templates__/vite-vue/src/App.vue +0 -6
- package/lib/__templates__/vite-vue/src/main.ts +0 -8
- package/lib/__templates__/vite-vue/src/router/index.ts +0 -17
- package/lib/__templates__/vite-vue/src/views/Home.vue +0 -38
- package/lib/__templates__/vite-vue/src/vite-env.d.ts +0 -8
- package/lib/__templates__/vite-vue/tailwind.config.js +0 -9
- package/lib/__templates__/vite-vue/template.config.js +0 -127
- package/lib/__templates__/vite-vue/tsconfig.json +0 -17
- package/lib/__templates__/vite-vue/vite.config.ts +0 -28
- /package/lib/__templates__/{vite-vue → nuxt-vue}/.coze +0 -0
- /package/lib/__templates__/{vite-vue → nuxt-vue}/_npmrc +0 -0
|
Binary file
|
|
@@ -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
|
|
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
|
|
37
|
+
echo "Starting Nuxt dev server on port ${PORT}..."
|
|
31
38
|
|
|
32
|
-
npx
|
|
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,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
|
+
}
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
"name": "
|
|
67
|
-
"description": "
|
|
68
|
-
"location": "./
|
|
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
69
|
"paramsSchema": {
|
|
70
70
|
"type": "object",
|
|
71
71
|
"properties": {
|
|
@@ -80,14 +80,14 @@
|
|
|
80
80
|
"default": 5000,
|
|
81
81
|
"minimum": 1024,
|
|
82
82
|
"maximum": 65535,
|
|
83
|
-
"description": "
|
|
83
|
+
"description": "Development server port (for Nuxt dev server)"
|
|
84
84
|
},
|
|
85
|
-
"
|
|
85
|
+
"hmrPort": {
|
|
86
86
|
"type": "number",
|
|
87
|
-
"default":
|
|
87
|
+
"default": 6000,
|
|
88
88
|
"minimum": 1024,
|
|
89
89
|
"maximum": 65535,
|
|
90
|
-
"description": "
|
|
90
|
+
"description": "Hot Module Replacement (HMR) port"
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
93
|
"required": [],
|
|
@@ -95,9 +95,9 @@
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
|
-
"name": "
|
|
99
|
-
"description": "
|
|
100
|
-
"location": "./
|
|
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
101
|
"paramsSchema": {
|
|
102
102
|
"type": "object",
|
|
103
103
|
"properties": {
|
|
@@ -112,14 +112,14 @@
|
|
|
112
112
|
"default": 5000,
|
|
113
113
|
"minimum": 1024,
|
|
114
114
|
"maximum": 65535,
|
|
115
|
-
"description": "
|
|
115
|
+
"description": "H5 development server port"
|
|
116
116
|
},
|
|
117
|
-
"
|
|
117
|
+
"serverPort": {
|
|
118
118
|
"type": "number",
|
|
119
|
-
"default":
|
|
119
|
+
"default": 3000,
|
|
120
120
|
"minimum": 1024,
|
|
121
121
|
"maximum": 65535,
|
|
122
|
-
"description": "
|
|
122
|
+
"description": "NestJS backend server port"
|
|
123
123
|
}
|
|
124
124
|
},
|
|
125
125
|
"required": [],
|
|
@@ -127,9 +127,9 @@
|
|
|
127
127
|
}
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
|
-
"name": "vite
|
|
131
|
-
"description": "Vite
|
|
132
|
-
"location": "./vite
|
|
130
|
+
"name": "vite",
|
|
131
|
+
"description": "Vite(简单项目):`coze init ${COZE_WORKSPACE_PATH} --template vite`\n- 适用:轻量级 SPA、纯前端交互、仪表盘等轻量级项目。",
|
|
132
|
+
"location": "./vite",
|
|
133
133
|
"paramsSchema": {
|
|
134
134
|
"type": "object",
|
|
135
135
|
"properties": {
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# <%= appName %>
|
|
2
2
|
|
|
3
|
-
这是一个基于
|
|
3
|
+
这是一个基于 Express + Vite + TypeScript + Tailwind CSS 的全栈 Web 应用项目,由扣子编程 CLI 创建。
|
|
4
|
+
|
|
5
|
+
**核心特性:**
|
|
6
|
+
- 🚀 前端:Vite + TypeScript + Tailwind CSS
|
|
7
|
+
- 🔧 后端:Express + TypeScript,提供 RESTful API
|
|
8
|
+
- 🔥 开发模式:Vite HMR + Express API,单进程启动
|
|
9
|
+
- 📦 生产模式:Express 静态服务 + API,高性能部署
|
|
4
10
|
|
|
5
11
|
## 快速开始
|
|
6
12
|
|
|
@@ -33,19 +39,149 @@ coze start
|
|
|
33
39
|
## 项目结构
|
|
34
40
|
|
|
35
41
|
```
|
|
36
|
-
├──
|
|
37
|
-
├──
|
|
38
|
-
│ ├──
|
|
39
|
-
│
|
|
40
|
-
│ └──
|
|
41
|
-
├──
|
|
42
|
-
├──
|
|
43
|
-
|
|
42
|
+
├── server/ # 后端服务器目录
|
|
43
|
+
│ ├── index.ts # express 服务器入口
|
|
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
|
+
- `server.ts` - 服务器主入口,负责创建和启动 Express 应用
|
|
61
|
+
- `routes/` - API 路由模块,支持按功能拆分路由
|
|
62
|
+
- `vite.ts` - Vite 开发服务器和静态文件服务集成
|
|
63
|
+
|
|
64
|
+
- **`src/`** - 前端应用代码
|
|
65
|
+
- 所有前端相关代码都在这里
|
|
66
|
+
|
|
67
|
+
**工作原理:**
|
|
68
|
+
|
|
69
|
+
- **开发模式** (`coze dev`):
|
|
70
|
+
- 运行 `server/server.ts` 启动 Express 服务器
|
|
71
|
+
- Vite 以 middleware 模式集成到 Express
|
|
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
|
+
- Express 服务静态文件 + 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', (req, res) => {
|
|
93
|
+
res.json({
|
|
94
|
+
users: [
|
|
95
|
+
{ id: 1, name: 'Alice' },
|
|
96
|
+
{ id: 2, name: 'Bob' },
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// POST 请求示例
|
|
102
|
+
router.post('/api/users', (req, res) => {
|
|
103
|
+
const userData = req.body;
|
|
104
|
+
// 处理业务逻辑
|
|
105
|
+
res.json({
|
|
106
|
+
success: true,
|
|
107
|
+
user: userData,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// 动态路由参数
|
|
112
|
+
router.get('/api/users/:id', (req, res) => {
|
|
113
|
+
const userId = req.params.id;
|
|
114
|
+
res.json({
|
|
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 'express';
|
|
128
|
+
|
|
129
|
+
const router = Router();
|
|
130
|
+
|
|
131
|
+
router.get('/api/users', (req, res) => {
|
|
132
|
+
// 用户列表逻辑
|
|
133
|
+
res.json({ users: [] });
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
router.post('/api/users', (req, res) => {
|
|
137
|
+
// 创建用户逻辑
|
|
138
|
+
res.json({ success: true });
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
export default router;
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
然后在 `server/server.ts` 中注册:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import usersRouter from './routes/users';
|
|
148
|
+
|
|
149
|
+
// 注册路由
|
|
150
|
+
app.use(usersRouter);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**前端调用 API**
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// GET 请求
|
|
157
|
+
async function getUsers() {
|
|
158
|
+
const response = await fetch('/api/users');
|
|
159
|
+
const data = await response.json();
|
|
160
|
+
console.log(data);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// POST 请求
|
|
164
|
+
async function createUser(name: string) {
|
|
165
|
+
const response = await fetch('/api/users', {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
headers: {
|
|
168
|
+
'Content-Type': 'application/json',
|
|
169
|
+
},
|
|
170
|
+
body: JSON.stringify({ name }),
|
|
171
|
+
});
|
|
172
|
+
const data = await response.json();
|
|
173
|
+
console.log(data);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**API 最佳实践**
|
|
178
|
+
|
|
179
|
+
- ✅ 所有 API 路由以 `/api` 开头,避免与前端路由冲突
|
|
180
|
+
- ✅ 使用 RESTful 设计:GET 查询、POST 创建、PUT 更新、DELETE 删除
|
|
181
|
+
- ✅ 返回统一的响应格式:`{ success: boolean, data?: any, error?: string }`
|
|
182
|
+
- ✅ 添加错误处理和参数验证
|
|
183
|
+
|
|
184
|
+
### 2. 样式开发
|
|
49
185
|
|
|
50
186
|
**使用 Tailwind CSS**
|
|
51
187
|
|
|
@@ -219,17 +355,31 @@ console.log(apiUrl); // https://api.example.com
|
|
|
219
355
|
|
|
220
356
|
## 技术栈
|
|
221
357
|
|
|
222
|
-
|
|
358
|
+
**前端:**
|
|
359
|
+
- **构建工具**: Vite 7.x
|
|
223
360
|
- **语言**: TypeScript 5.x
|
|
224
361
|
- **样式**: Tailwind CSS 3.x
|
|
362
|
+
|
|
363
|
+
**后端:**
|
|
364
|
+
- **框架**: Express 4.x
|
|
365
|
+
- **内置中间件**: express.json(), express.urlencoded(), express.static()
|
|
366
|
+
|
|
367
|
+
**工具:**
|
|
225
368
|
- **包管理器**: pnpm 9+
|
|
369
|
+
- **运行时**: Node.js 18+
|
|
370
|
+
- **开发工具**: tsx (TypeScript 执行器)
|
|
226
371
|
|
|
227
372
|
## 参考文档
|
|
228
373
|
|
|
374
|
+
**前端:**
|
|
229
375
|
- [Vite 官方文档](https://cn.vitejs.dev/)
|
|
230
376
|
- [TypeScript 官方文档](https://www.typescriptlang.org/zh/docs/)
|
|
231
377
|
- [Tailwind CSS 文档](https://tailwindcss.com/docs)
|
|
232
378
|
|
|
379
|
+
**后端:**
|
|
380
|
+
- [Express 官方文档](https://expressjs.com/)
|
|
381
|
+
- [Express 中文文档](https://expressjs.com/zh-cn/)
|
|
382
|
+
|
|
233
383
|
## 重要提示
|
|
234
384
|
|
|
235
385
|
1. **必须使用 pnpm** 作为包管理器
|
|
@@ -237,3 +387,32 @@ console.log(apiUrl); // https://api.example.com
|
|
|
237
387
|
3. **使用 Tailwind CSS** 进行样式开发,支持响应式和暗色模式
|
|
238
388
|
4. **环境变量必须以 `VITE_` 开头** 才能在客户端代码中访问
|
|
239
389
|
5. **开发时使用 `coze dev`**,支持热更新和快速刷新
|
|
390
|
+
6. **API 路由以 `/api` 开头**,避免与前端路由冲突
|
|
391
|
+
7. **单进程架构**:开发和生产环境都是前后端在同一进程中运行
|
|
392
|
+
|
|
393
|
+
## 常见问题
|
|
394
|
+
|
|
395
|
+
**Q: 如何分离前后端端口?**
|
|
396
|
+
|
|
397
|
+
如果需要前后端分离部署,可以:
|
|
398
|
+
- 前端:使用 `npx vite` 单独启动(默认端口 5173)
|
|
399
|
+
- 后端:修改 `server.ts`,移除 Vite middleware,单独启动
|
|
400
|
+
|
|
401
|
+
**Q: 如何添加数据库?**
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
# 安装数据库客户端(以 PostgreSQL 为例)
|
|
405
|
+
pnpm add pg
|
|
406
|
+
pnpm add -D @types/pg
|
|
407
|
+
|
|
408
|
+
# 在 server.ts 中使用
|
|
409
|
+
import { Pool } from 'pg';
|
|
410
|
+
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**Q: 如何部署?**
|
|
414
|
+
|
|
415
|
+
1. 运行 `coze build` 构建前后端
|
|
416
|
+
2. 将整个项目上传到服务器
|
|
417
|
+
3. 运行 `pnpm install --prod`
|
|
418
|
+
4. 运行 `coze start` 启动服务
|
|
@@ -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([
|
|
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 Express + Vite (HTML + CSS + TS + Node API)",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "bash ./scripts/build.sh",
|
|
7
7
|
"dev": "bash ./scripts/dev.sh",
|
|
@@ -12,15 +12,21 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@supabase/supabase-js": "2.95.3",
|
|
15
|
-
"dotenv": "^17.2.3"
|
|
15
|
+
"dotenv": "^17.2.3",
|
|
16
|
+
"express": "^4.21.2"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
19
|
+
"@types/express": "^5.0.0",
|
|
20
|
+
"@types/node": "^22.10.5",
|
|
18
21
|
"autoprefixer": "^10.4.20",
|
|
19
22
|
"coze-coding-dev-sdk": "^0.7.16",
|
|
23
|
+
"esbuild": "^0.24.2",
|
|
20
24
|
"eslint": "^9",
|
|
21
25
|
"only-allow": "^1.2.2",
|
|
22
26
|
"postcss": "^8.4.49",
|
|
23
27
|
"tailwindcss": "^3.4.17",
|
|
28
|
+
"tsup": "^8.3.5",
|
|
29
|
+
"tsx": "^4.19.2",
|
|
24
30
|
"typescript": "^5.6.0",
|
|
25
31
|
"typescript-eslint": "^8",
|
|
26
32
|
"vite": "^7.2.4"
|
|
@@ -31,7 +37,8 @@
|
|
|
31
37
|
},
|
|
32
38
|
"pnpm": {
|
|
33
39
|
"overrides": {
|
|
34
|
-
"esbuild": "^0.27.2"
|
|
40
|
+
"esbuild": "^0.27.2",
|
|
41
|
+
"is-generator-function": "1.0.10"
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
44
|
}
|