全栈项目|小书架|服务器开发-Koa全局路由实现

什么是路由

路由就是具体的访问路径,指向特定的功能模块。一个api接口是由ip(域名)+端口号+路径组成,例如 :https://www.npmjs.com/package/koa-router就是一个路由,指向了koa-routernpm页面。node

为何须要 koa-router 路由

固然不须要koa-router也能实现路由功能,经过ctx.request.path去指定路径实现。例子以下:npm

const koa = require('koa2')
const app = new koa()

app.use(async (ctx, next) => {
    if (ctx.request.path === '/') { // 首页
      ctx.response.status = 200
      ctx.response.body = 'index'
    } else if (ctx.request.path === '/list') { // 列表页
      ctx.response.status = 200
      ctx.response.body = 'list'
    } else {
    	ctx.throw(404, 'Not found') // 404
    }
  await next()
})

app.listen(3000)

参考:Koa 路由api

以上代码只是实现两个接口,就写了很多代码,而写是多层的判断代码,可读性已经不好了,这时候怎么办?微信

是否是能够将以上代码抽取出去,经过中间件的方式去实现。app

结果是能够的,koa-router就是这样作的。使用koa-router实现的例子以下:less

  1. app.js 入口
  2. urls/home.js home 页面的路由

app.js 的代码以下koa

// 路由模块使用前须要先安装和实例化
const Router = require('koa-router')
const router = new Router()

// 首页
app.use(async (ctx, next) => {
    if (ctx.request.path === '/') {
      ctx.response.status = 200
      ctx.response.body = 'index'
    }
    await next()
})

// 其余页面经过 router 加载
let urls = fs.readdirSync(__dirname + '/urls')
urls.forEach((element) => {
    let module = require(__dirname + '/urls/' + element)
    /*
      urls 下面的每一个文件负责一个特定的功能,分开管理
      经过 fs.readdirSync 读取 urls 目录下的全部文件名,挂载到 router 上面
    */
    router.use('/' + element.replace('.js', ''), module.routes(), module.allowedMethods())
})
app.use(router.routes())

urls/home.js 的代码以下async

const Router = require('koa-router')
const home = new Router()

// /home
home.get('/', async (ctx, next) => {
    ctx.response.status = 200
    ctx.response.body = 'home'
    await next()
})

// home/list
home.get('/list', async (ctx, next) => {
    ctx.response.status = 200
    ctx.response.body = 'home-list'
    await next()
})

module.exports = home

经过以上代码基本已经实现了全局路由的功能了,剩下得就是在urls包下建立对应的文件便可,参考home.js便可。函数

可是这里的代码仍是不够完美,app.js做为入口文件,这里的代码仍是有点多了;并且首页和home的路由是分开来实现的。再并且urls路径是固定的,后续文件夹名称或者位置改变都会出现问题。ui

那么如何实现呢?
这里介绍一种思路:

  1. app.js中的代码抽取出来,让app.js尽可能简单
  2. 将首页和其余页面都在全局路由中实现

优雅的全局路由实现

经过npm引入require-directory

require-directory npm包的做用是:

递归地遍历指定目录,对每一个文件进行require()

这里也是利用了这个包去实现的。具体实现以下:

  1. core目录下建立InitManager.js
const requireDirectory = require('require-directory')
const Router = require('koa-router')
/**
* 加载全局路由
*/
static initLoadRouters(app){
   // 加载工做目录下的 app/api 下的路径
   const apiDirectory = `${process.cwd()}/app/api`
   
   // 参数:第一个参数固定参数module
   // 第二个参数要加载的模块的文件路径
   // 第三个参数:每次加载一个参数执行的函数
   requireDirectory(module, apiDirectory, {
       visit: whenLoadModule
   })
   
   function whenLoadModule(obj) {
       if(obj instanceof Router ){
           app.use(obj.routes())
       }
   }
}

module.exports = InitManager

从上面的实现方式能够看出这里使用了process.cwd()获取路径,而原有的代码中是经过__dirname去获取路径,那么两者有什么区别呢?

NodeJsprocess.cwd()__dirname的区别
process.cwd() 是当前执行node命令时候的文件夹地址 ——工做目录,保证了文件在不一样的目录下执行时,路径始终不变
__dirname 是被执行的js 文件的地址 ——文件所在目录

  1. app.js中加载这个方法便可。
const app = new Koa()
InitManager.initLoadRouters(app)
  1. app/api下建立相应的接口文件便可,如home.js

咨询请加微信:轻撩便可。
在这里插入图片描述

相关文章
相关标签/搜索