Koa3 CLI
基于 Koa3 的脚手架项目
2025年4月28日,Node.js 生态圈迎来了一场重磅升级——Koa.js 3.0 正式发布!自2017年启动开发计划,历经8年长跑,由 Express 原班人马打造的经典轻量级 Web 框架,终于以全新姿态回归视野。Koa 3.0 不仅是一次版本号的跃迁,更是 Node.js 现代化进程的重要里程碑。
快速开始 →🚀 轻量高效
基于 Koa3,性能优异,代码简洁
📁 清晰结构
规范统一,易于维护
🔧 多环境配置
支持 development/production 环境配置
🏗️ MVC 架构
Controller/Service/Model 分层清晰
🔌 中间件支持
灵活的中间件系统,易于扩展
✅ 错误处理
统一的错误处理机制
⚡ CLI 工具
一键创建项目,快速上手
快速开始
使用 CLI 工具创建项目(推荐)
全局安装 CLI
npm install -g koa3-cli
创建新项目
koa3-cli create my-project
cd my-project
npm install
npm run dev
或者使用 npx(无需安装):
npx koa3-cli create my-project
手动安装项目
如果你已经有一个项目,可以手动安装依赖:
安装依赖
npm install
启动项目
开发环境
使用 nodemon 自动重启:
npm run dev
生产环境
npm start
访问应用
启动成功后,你可以访问:
- 首页: http://localhost:3000
- API 示例: http://localhost:3000/api/user
- 文档: http://localhost:3000/index.html
CLI 命令
CLI 工具支持以下命令:
koa3-cli create <project-name>- 创建新项目koa3-cli --help- 查看帮助信息koa3-cli --version- 查看版本信息
环境配置
项目支持多环境配置,通过 NODE_ENV 环境变量控制:
development或local: 加载config.local.jsproduction: 加载config.prod.js- 默认: 加载
config.default.js
可以通过 .env 文件配置环境变量(参考 env.example)。
下一步
项目结构
koa3-cli/
├── app/ # 应用代码目录
│ ├── controller/ # 控制器目录
│ │ ├── home.js # 首页控制器
│ │ └── user.js # 用户控制器
│ ├── service/ # 服务层目录
│ │ └── user.js # 用户服务
│ ├── model/ # 数据模型目录
│ │ └── user.js # 用户模型
│ ├── middleware/ # 中间件目录
│ │ ├── index.js # 中间件入口
│ │ └── auth.js # 认证中间件示例
│ ├── router.js # 路由配置
│ └── view/ # 视图模板目录(可选)
│ └── docs.ejs # 页面模板
├── bin/ # CLI 工具目录(仅 CLI 包)
│ └── cli.js # CLI 入口文件
├── config/ # 配置文件目录
│ ├── config.default.js # 默认配置
│ ├── config.local.js # 本地开发配置
│ └── config.prod.js # 生产环境配置
├── public/ # 静态资源目录
│ ├── docs/ # 文档资源
│ └── index.html # 文档首页
├── app.js # 应用入口文件
├── package.json # 项目配置
├── env.example # 环境变量示例
└── README.md # 项目说明
目录说明
app/
应用代码目录,包含所有业务逻辑代码。
controller/
控制器目录,处理 HTTP 请求和响应。
// app/controller/user.js
class UserController {
async list(ctx) {
ctx.body = await userService.getUserList();
}
}
service/
服务层目录,处理业务逻辑。
// app/service/user.js
class UserService {
async getUserList() {
return await userModel.findAll();
}
}
model/
数据模型目录,处理数据访问。
// app/model/user.js
class UserModel {
async findAll() {
// 数据库查询逻辑
}
}
middleware/
中间件目录,处理请求预处理和后处理。
// app/middleware/index.js
module.exports = async (ctx, next) => {
// 中间件逻辑
await next();
};
config/
配置文件目录,包含不同环境的配置。
public/
静态资源目录,存放静态文件。
配置说明
环境配置
项目支持多环境配置,通过 NODE_ENV 环境变量控制:
development或local: 加载config.local.jsproduction: 加载config.prod.js- 默认: 加载
config.default.js
配置文件会按顺序加载,后面的配置会覆盖前面的配置。
环境变量
可以通过 .env 文件配置环境变量(参考 env.example):
# 运行环境
NODE_ENV=development
# 服务端口
PORT=3000
# 应用密钥(多个密钥用逗号分隔)
KEYS=your-secret-key-1,your-secret-key-2
# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_NAME=test
# Redis配置
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
# 日志级别
LOG_LEVEL=info
配置项说明
基础配置
{
name: 'koa3-cli', // 应用名称
env: 'development', // 运行环境
port: 3000, // 服务端口
keys: ['secret-key'] // 应用密钥
}
静态资源配置
static: {
enable: true, // 是否启用
dir: 'public', // 静态文件目录
options: {
maxAge: 365 * 24 * 60 * 60 * 1000, // 缓存时间
gzip: true // 是否启用 gzip
}
}
视图配置
view: {
enable: true, // 是否启用
root: 'app/view', // 视图文件目录
options: {
extension: 'ejs', // 默认扩展名
map: {
html: 'ejs' // 文件扩展名映射
}
}
}
数据库配置
database: {
client: 'mysql',
connection: {
host: 'localhost',
port: 3306,
user: 'root',
password: '',
database: 'test'
},
pool: {
min: 2,
max: 10
}
}
Redis配置
redis: {
host: 'localhost',
port: 6379,
password: '',
db: 0
}
日志配置
logger: {
level: 'info', // 日志级别: debug, info, warn, error
dir: 'logs' // 日志目录
}
开发指南
添加新的控制器
1. 在 app/controller/ 目录下创建控制器文件
// app/controller/product.js
const productService = require('../service/product');
class ProductController {
async list(ctx) {
try {
const products = await productService.getList();
ctx.body = products;
} catch (error) {
ctx.throw(500, error.message);
}
}
async detail(ctx) {
const { id } = ctx.params;
const product = await productService.getById(id);
if (!product) {
ctx.status = 404;
ctx.body = { message: 'Product not found' };
return;
}
ctx.body = product;
}
}
module.exports = new ProductController();
2. 在 app/router.js 中注册路由
const productController = require('./controller/product');
router.get('/api/product', productController.list);
router.get('/api/product/:id', productController.detail);
添加新的服务
在 app/service/ 目录下创建服务文件,处理业务逻辑:
// app/service/product.js
const productModel = require('../model/product');
class ProductService {
async getList() {
return await productModel.findAll();
}
async getById(id) {
return await productModel.findById(id);
}
async create(productData) {
// 数据验证
if (!productData.name) {
throw new Error('Product name is required');
}
return await productModel.create(productData);
}
}
module.exports = new ProductService();
添加新的模型
在 app/model/ 目录下创建模型文件,处理数据访问:
// app/model/product.js
class ProductModel {
async findAll() {
// 数据库查询逻辑
// return await db.query('SELECT * FROM products');
}
async findById(id) {
// return await db.query('SELECT * FROM products WHERE id = ?', [id]);
}
async create(productData) {
// return await db.insert('products', productData);
}
}
module.exports = new ProductModel();
添加中间件
在 app/middleware/ 目录下创建中间件文件:
// app/middleware/logger.js
module.exports = async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
};
然后在 app/middleware/index.js 中引入使用:
const logger = require('./logger');
module.exports = async (ctx, next) => {
await logger(ctx, next);
// 其他中间件...
};
错误处理
控制器中的错误会自动被错误处理中间件捕获:
// 抛出错误
ctx.throw(400, 'Bad Request');
// 或者
throw new Error('Something went wrong');
错误会被统一处理并返回:
{
"success": false,
"message": "Error message",
"stack": "..." // 仅在开发环境显示
}
响应格式
API 请求会自动统一响应格式:
{
"success": true,
"data": {
// 响应数据
}
}
如果响应已经是 { success: true/false } 格式,则不会再次包装。
API 文档
本文档描述了 Koa3 CLI 提供的所有 API 接口。
基础信息
- Base URL:
http://localhost:3000 - Content-Type:
application/json
响应格式
所有 API 响应都遵循统一的格式:
成功响应
{
"success": true,
"data": {
// 响应数据
}
}
错误响应
{
"success": false,
"message": "错误信息",
"stack": "..." // 仅在开发环境显示
}
API 列表
- 用户接口 - 用户相关的 CRUD 操作
用户接口
用户相关的 CRUD 操作接口。
获取用户列表
获取所有用户列表。
请求
GET /api/user
响应
{
"success": true,
"data": [
{
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"createdAt": "2024-01-01T00:00:00.000Z"
},
{
"id": 2,
"name": "李四",
"email": "lisi@example.com",
"createdAt": "2024-01-01T00:00:00.000Z"
}
]
}
获取用户详情
根据用户 ID 获取用户详情。
请求
GET /api/user/:id
路径参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | number | 用户ID |
响应
{
"success": true,
"data": {
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
错误响应
{
"success": false,
"message": "User not found"
}
创建用户
创建新用户。
请求
POST /api/user
Content-Type: application/json
请求体
{
"name": "张三",
"email": "zhangsan@example.com"
}
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 用户姓名 |
| string | 是 | 用户邮箱 |
响应
{
"success": true,
"data": {
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
更新用户
更新用户信息。
请求
PUT /api/user/:id
Content-Type: application/json
路径参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | number | 用户ID |
请求体
{
"name": "李四",
"email": "lisi@example.com"
}
响应
{
"success": true,
"data": {
"id": 1,
"name": "李四",
"email": "lisi@example.com",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-02T00:00:00.000Z"
}
}
删除用户
删除指定用户。
请求
DELETE /api/user/:id
路径参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | number | 用户ID |
响应
204 No Content
错误响应
{
"success": false,
"message": "User not found"
}