全棧項目|小書架|服務器開發-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

以上代碼只是實現兩個接口,就寫了很多代碼,而寫是多層的判斷代碼,可讀性已經不好了,這時候怎麼辦?bash

是否是能夠將以上代碼抽取出去,經過中間件的方式去實現。微信

結果是能夠的,koa-router就是這樣作的。使用koa-router實現的例子以下:app

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

app.js 的代碼以下less

// 路由模塊使用前須要先安裝和實例化
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 的代碼以下koa

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便可。async

可是這裏的代碼仍是不夠完美,app.js做爲入口文件,這裏的代碼仍是有點多了;並且首頁和home的路由是分開來實現的。再並且urls路徑是固定的,後續文件夾名稱或者位置改變都會出現問題。函數

那麼如何實現呢? 這裏介紹一種思路:

  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

諮詢請加微信:輕撩便可。

在這裏插入圖片描述
相關文章
相關標籤/搜索