Koa项目基础框架搭建

  • 项目初始化
  • 项目自动重启
  • 配置ES6语法
  • 基本目录搭建
    • 配置env信息
    • 自动加载路由
    • 统一异常处理
      • 自定义异常
      • 异常处理中间件
    • 中间件配置
    • 目录别名配置

项目初始化

mkdir koa-demo
yarn init
yarn add koa koa-router

这里使用 yarn 包管理器进行项目依赖管理。

// index.js
const app = require('./app');const port = 4000;app.listen(port, () => {console.log(`Koa项目启动成功:http://localhost:${port}`);
});
// app.js
const Koa = require('koa');
const Router = require('koa-router');const app = new Koa();const router = new Router();router.get('/', async (ctx, next) => {ctx.body = '<h1>这是主页</h1>';
});router.get('/hello/:name', async (ctx, next) => {ctx.body = `<h1>你好,${ctx.params.name}</h1>`;
});app.use(router.routes());module.exports = app;
// package.json
{"name": "koa-demo","version": "1.0.0","description": "koa项目基本目录结构","main": "index.js","repository": "https://gitee.com/ljw_full/koa-demo.git","author": "ljw","license": "MIT","scripts": {"dev": "node index.js"},"dependencies": {"koa": "^2.11.0","koa-router": "^8.0.8"}
}

这就是一个最简单的Koa项目了,使用yarn dev 后就会在4000端口启动一个WEB服务:

项目自动重启

在开发时,经常需要改代码看效果,但是每次手动关闭项目,启动项目很麻烦,所以就用到 nodemon 这个自动重启工具,每次修改完代码保存后,就可以自动重启整个项目查看效果了。

npm i nodemon -g 这里我使用全局安装 nodmeon ,因为我只配置了 npm 的path,所以这里就用 npm 安装 nodemon

修改 package.jsonscript.dev 脚本为:nodemon index.js

配置ES6语法

在这里你使用 import 会发现报错 SyntaxError: Unexpected identifier(Node支持大部分ES6语法,不过这个import 关键字却没有)

这里需要使用 babel 来进行编译才可以执行:

yarn add babel-cli babel-preset-es2015 -D

然后再根目录添加一个新文件 .babelrc

{"presets": ["es2015"]
}

启动脚本配置如下:

{"scripts": {"dev": "nodemon index.js --exec babel-node","prod": "babel-node index.js"},
}

基本目录搭建

一个项目的开发都有一套良好的目录结构,什么代码放哪个目录下。

.
├── app.js
├── index.js                   # 项目启动入口
├── package.json
├── src├── main                   # 项目代码│   ├── common             # 通用模块│   ├── config             # 配置│   ├── controller         # 接口│   ├── middleware         # 中间件│   ├── model              # 模型层│   └── service            # 服务层│   └── util               # 工具层└── test                   # 测试目录

这里的 app.js 和 index.js 分开来写是为了方便测试接口

配置env信息

通常一些配置都会分为开发环境,测试环境,生成环境,最典型的就是数据库连接信息了。

这里使用 dotenv 来配置 env:yarn add docenv

然后创建一个 .env 文件:

NODE_ENV=devPORT=4000

index.js 中最上方添加一行代码:

import 'dotenv/config';
import Koa from 'koa';
import router from './src/main/router';const app = new Koa();// 加载所有路由
router(app);export default app;

一般 .env 文件不会进入git版本库,我通常都会放一个 .env.example 里面写着样例配置,然后根据这个 .env.example 复制出 .env 文件编写真正的信息。

你的一些私密信息都可以写在 .env 文件里,例如你的数据库连接信息,一些第三方的私钥密钥信息等。

自动加载路由

开发一个项目,通常都会有很多的接口,所以不可能把接口都写在app.js里面,我这里把接口都放到了src/main/controller 目录下,例如现在我编写了一个测试模块:

// src/main/api/TestController.js
import Router from 'koa-router';let testRouter = new Router({prefix: '/test'
});testRouter.get('/', async ctx => {ctx.body = '<h1>测试主页</h1>';
});testRouter.get('/hello/:name', async ctx => {ctx.body = `<h1>你好啊,${ctx.params.name}</h1>`;
});export default testRouter;

这里使用一个require-directory库,他可以很方便的递归检索目录下的文件:yarn add require-directory

// src/main/router.js
import requireDirectory from 'require-directory';
import Router from 'koa-router';export default app => {requireDirectory(module, './controller', {visit: (obj) => {if (obj.default instanceof Router) {app.use(obj.default.routes());}}})
}

这里遍历递归 src/main/controller 目录,visit 接受一个函数,obj 就是那个文件export的对象,如果这个 obj 是 Router 实例,就加载到路由,这样子,你在 src/main/controller 下编写多少个文件都可以自动加载。

最后在 app.js 中引入这个 router.js 文件:

import Koa from 'koa';
import router from './src/main/router';const app = new Koa();// 加载所有路由
router(app);export default app;

统一异常处理

自定义异常

export const COMMON_ERROR_CODE = 500;
export const PARAM_ERROR_CODE = 501;/*** 通用异常*/
export class CommonError extends Error {constructor(code = COMMON_ERROR_CODE, msg = '服务器异常') {super();this.code = code;this.msg = msg;}
}/*** 参数异常*/
export class ParamError extends CommonError {constructor(msg = '参数异常') {super(PARAM_ERROR_CODE, msg);}
}

异常处理中间件

// src/main/middleware/globalError.js
import { CommonError } from '../common/CommonError';export default () => {return async (ctx, next) => {try {await next();} catch (err) {if (err instanceof CommonError) {ctx.body = err;} else {ctx.body = new CommonError();}}};
};

不过这里的 err instanceof CommonError 可能一直都是 false ,需要添加一个 babel 插件:yarn add babel-plugin-transform-builtin-extend -D

.babelrc 中配置一下插件:

{"presets": ["es2015"],"plugins": [["babel-plugin-transform-builtin-extend",{ "globals": ["Error", "Array"] }]]
}

最后在 app.js 中引入中间件:

import Koa from 'koa';
import router from './src/main/router';
import globalError from './src/main/middleware/globalError';const app = new Koa();// 全局异常处理
app.use(globalError());// 加载所有路由
router(app);export default app;

使用:

import Router from 'koa-router';
import { ParamError, CommonError } from '../common/CommonError';let testRouter = new Router({prefix: '/test'
});testRouter.get('/exception', async ctx => {// ctx.body = ctx._matchedRouteName.msg;throw new ParamError('缺少参数');
});export default testRouter;

中间件配置

中间件会统一放到 src/main/middleware 目录下,如果中间件过多在 app.js 中引入也是比较麻烦,所以这里可以写个中间件配置。

配置文件在 src/main/config 目录下:

// src/main/config/index.js
export default {middlewares: ['globalError']
};

这里的 middlewares 是个数组,存放的是 middleware 目录下的中间件的文件名,带不带 .js 都可以。

然后在 middleware.js 中处理中间件:

// src/main/middleware.js
import config from './config';export default (app) => {if (config.middlewares) {let middleware;config.middlewares.forEach(item => {middleware = require(`./middleware/${item}`).default;app.use(middleware());});}
};

app.js 中处理 middleware.js

import Koa from 'koa';
import router from './src/main/router';
import middleware from './src/main/middleware';const app = new Koa();// 中间件处理
middleware(app);// 加载所有路由
router(app);export default app;

添加一个中间件,在 config/index.jsmiddlewares 数组中添加一下中间件文件名即可。

目录别名配置

如果的你的目录层次够深,可能会遇到 import '../../../src/main/config'; 的代码,此时我们可以使用 @main 来代替 src/main 目录。

安装:yarn add module-alias

package.json 中添加:

{"_moduleAliases": {"@main": "./src/main"}
}

app.js 中引入一个依赖:

import 'module-alias/register';
import Koa from 'koa';
import router from '@main/router.js';
import middleware from '@main/middleware';const app = new Koa();// 中间件处理
middleware(app);// 加载所有路由
router(app);export default app;

接下来下面的所有地方都可以使用 @main 这个目录别名了。

但是此时 VScode 的路径提示可能会没有了,需要在 根目录下添加一个 jsconfig.json 文件:

{"compilerOptions": {"target": "ES6","module": "commonjs","allowSyntheticDefaultImports": true,"baseUrl": "./","paths": {"@main/*": ["src/main/*"]}},"exclude": ["node_modules"]
}

点击查看源码

相关文章:

  • Koa入门(二)—— 使用Sequelize连接Mysql
  • Koa入门(三)—— Koa项目自动化测试
  • Koa入门(四)—— Koa使用JWT做权限认证
  • Koa入门(五)—— 使用log4j记录日志

Koa入门(一)—— Koa项目基础框架搭建相关推荐

  1. 原生微信小程序项目基础框架搭建

    原生微信小程序项目基础框架搭建 文件目录结构 1. 环境变量(开发环境, 线上环境,测试环境)便于在不同环境的切换 接口的url webview的前缀url 埋点相关的环境参数 本地存储的环境变量配置 ...

  2. vue移动端项目基础框架搭建

    本文章,主要提供vue移动端项目基础框架搭建思路,每个独立的模块网上有很多相关的文档. 移动端vue项目基础框架搭建,主要包括6个步骤 项目使用的脚手架vue-cli搭建模板,2.使用淘宝lib-fl ...

  3. Doom Emacs入门:通过Doom Emacs框架搭建一个基本的Python开发环境及其基本操作

    Doom Emacs入门:通过Doom Emacs框架搭建一个基本的Python开发环境及其基本操作 一.写在前面 1.1 明确目标:搭建一个完整的Python开发环境 1.2 前置工作 二.Doom ...

  4. uniApp介绍篇-1.基础框架搭建与排坑备忘

    基础框架搭建与排坑备忘 一.uniApp介绍与注意点 1.目录结构 2.跳转页面 3.条件编译 4.生命周期 5.样式布局 6.图片引用 7.html标签 8.JsApi 9.小程序组件支持 10.事 ...

  5. nodejs php做平台,用nodejs做一套康养管理系统(1)--基础框架搭建

    用nodejs做一套康养管理系统(1)--基础框架搭建 这两天准备开始一个康养项目管理系统的开发,闲来无事想将整个流程写下来,并将本项目开发代码开源.首先本次先梳理下结构,画一个拓扑结构图,再根据结构 ...

  6. vue.js项目实战运用篇之抖音视频APP-第二节:项目基础架构搭建

    [温馨提示]:若想了解更多关于本次项目实战内容,可转至vue.js项目实战运用篇之抖音视频APP-项目规划中进一步了解项目规划. [项目地址] 项目采用Git进行管理,最终项目将会发布到GitHub中 ...

  7. Maven搭建多模块企业级项目+SSM框架搭建

    一.开发环境: 0.Eclipse Java EE IDE for Web Developers:  /Version: 2018-09 (4.9.0)  /  Build id: 20180917- ...

  8. 亲手搭建一个基于Asp.Net WebApi的项目基础框架1

    目标:教大家搭建一个简易的前后端分离的项目框架. 目录: 1:关于项目架构的概念 2:前后端分离的开发模式 3:搭建框架的各个部分 这段时间比较闲,所以想把之前项目里用到的一些技术写到博客里来,分享给 ...

  9. Iris学习入门基础框架搭建

    项目介绍 一款 Go 语言基于Iris.Layui.MySQL等框架精心打造的一款模块化.高性能.企业级的敏捷开发框架,本着简化开发.提升开发效率的初衷触发,框架自研了一套个性化的组件,实现了可插拔的 ...

最新文章

  1. 库克:苹果收取 30% 佣金很合理!
  2. Https 公钥、私钥、证书
  3. VS2013崩溃,无法打开项目的解决方案
  4. 面试官系统精讲Java源码及大厂真题 - 45 Socket 源码及面试题
  5. Zend Framework实例教程三
  6. Vhost dataplane in Qemu | PDF
  7. Qt之QMessageBox详解
  8. 查找和杀掉postgresql堵塞的会话
  9. SWEBOK软件工程知识体系 - 7.软件工程管理
  10. 江西省电子专题大赛考点讲解七:NE555定时器
  11. Android简易计算器的制作(源码)(两种方法)
  12. 愚你相遇,好幸运:遇见你,遇见了最好的自己
  13. 九位SEO专家分享他们对Google核心更新的看法
  14. 面试官:你对MySQL中的索引了解多少?
  15. 基于OpenSSL的CA建立及证书签发(签发单域名/IP)
  16. dz邮箱验证怎么设置_详细步骤!Discuz如何设置通过 SOCKET 连接 SMTP 服务器发送(支持 ESMTP 验证)实现论坛邮箱验证功能...
  17. Python个人项目1 --------电商项目
  18. wifi安全模式是什么_WIFI的完整形式是什么?
  19. dbd:oracle下载,perl DBD::oracle
  20. 如何在路由器里设置L2TP和PPTP拨号?飞速云科技

热门文章

  1. mysql wm concat_wm_concat 多行字符串拼接(示例代码)
  2. 生物信息学|利用层注意图卷积网络预测药物-疾病关联
  3. 简单爬虫 爬知乎日报
  4. D. DS哈希查找与增补(表尾插入)
  5. 一键重装系统win7方法分享
  6. 数据库中olap和oltp的区别
  7. 玩具租赁项目适合大学生吗?
  8. Python 机器人学 —— 坐标系变换动画
  9. 054 《北大经济课》读后感
  10. COMFORT 美酒 | 人头马一开 我们耀精彩