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 环境变量控制:

  • developmentlocal: 加载 config.local.js
  • production: 加载 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 环境变量控制:

  • developmentlocal: 加载 config.local.js
  • production: 加载 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 操作接口。

获取用户列表

获取所有用户列表。

请求

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 用户姓名
email 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"
}