0. 简介
1. 运行
1.1. Node 版本
Koa2 使用了 async/await 等新语法,请保证 Node 版本在 7.6 及以上。
1.2. 命令
# 安装 pm2 到全局 $ npm install -g pm2 # 安装 less.js $ npm install --save less.js # JS 代码校验 $ npm run eslintfix $ npm run eslint # 开发 $ npm run dev # 启动项目 $ npm start # 停止项目 $ npm run stop
2. 规范
2.1. 目录结构
├─ src 源码 │ ├─ app 业务代码 │ │ ├─ controllers 控制器:用于解析用户输入,处理后返回相应的结果 │ │ ├─ models 模型 :用于定义数据模型 │ │ ├─ services 服务 :用于编写业务逻辑层,比如连接数据库,调用第三方接口等 │ │ └─ views 视图 :用于放置模板文件,返回客户端的视图层 │ │ │ ├─ extends 扩展 │ ├─ middlewares 中间件 │ ├─ public 静态资源 │ ├─ router URL 路由 │ ├─ utils 工具库 │ └─ index.js 入口:用于自定义启动时的初始化工作,比如启动 https,调用中间件、路由等 │ ├─ .eslintrc eslint 配置文件 ├─ nodemon.json nodemon 配置文件 ├─ package.json npm 配置文件 ├─ processes.json pm2 配置文件
2.2. 添加自定义对象
为了提高开发效率,这里人为的将一些自定义对象挂载到 app 下,用 $ 前缀命名,与 Koa.js 内置对象做区分。
- app.$consts:常量和配置
- app.$helpers:辅助函数
- app.$model:公用模型对象
- app.$Service:服务基类
- app.$Controller:控制器基类
- app.$models:模型集合
- app.$services:服务集合
- app.$controllers:控制器集合
2.3. 示例
完整的示例代码:github.com/zhaotoday/l…。
2.3.1. 模型
src/app/models/articles.js
module.exports = app => { const {ID, SHORT_RELATED_ID, NAME, TITLE, SUBTITLE, DESCRIPTION, CONTENT, PICTURES, ORDER} = app.$model.columns return app.$model.define('articles', { id: ID, category_id: SHORT_RELATED_ID, author: NAME, title: TITLE, subtitle: SUBTITLE, description: DESCRIPTION, content: CONTENT, pictures: PICTURES, order: ORDER }) }
2.3.2. 服务
src/app/services/articles.js
module.exports = app => { return class extends app.$Service { constructor () { super() this.model = app.$models.articles } } }
2.3.3. 控制器
src/app/controllers/articles.js
module.exports = app => { const service = app.$services.articles return class extends app.$Controller { async index (ctx, next) { await ctx.render('articles', { items: await service.find({offset: 0, limit: 10}) }) } } }
2.3.4. 视图
src/app/views/articles.ejs
<%- JSON.stringify(items) %>
2.3.5. API
src/app/controllers/apis/v1/articles.js
module.exports = app => { const service = app.$services.articles return class extends app.$Controller { async index (ctx, next) { ctx.response.body = ctx.send({ status: 200, data: await service.find({offset: 0, limit: 10}) }) } } }
2.3.6. 路由
src/router/routes/articles.js
module.exports = (app, router) => { router.get('/articles', app.$controllers.articles.index) }
2.4. 扩展
2.4.1. 常量及配置
src/extends/consts.js
// 监听端口 const PORT = 3001 // MySQL 数据库配置 const DB = { database: 'hzzww0n', username: 'hzzww0n_f', password: 'aaaaaa111111', options: { host: 'wvort936.669.dnstoo.com', port: 4024, dialect: 'mysql', define: { underscored: true } } } // Redis 配置 const REDIS = {} // JWT 配置 const JWT = { secret: 'jwt_secret', expiresIn: '5h' } module.exports = app => { return { PORT, DB, REDIS, JWT } }
2.4.2. 辅助方法
src/extends/helpers.js
module.exports = app => { return { myFunc () {} } }