路由就是具体的访问路径,指向特定的功能模块。一个
api
接口是由ip(域名)+端口号
+路径组成,例如 :https://www.npmjs.com/package/koa-router
就是一个路由,指向了koa-router
的npm
页面。node
固然不须要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
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
那么如何实现呢?
这里介绍一种思路:
app.js
中的代码抽取出来,让app.js
尽可能简单经过npm
引入require-directory
require-directory npm
包的做用是:
递归地遍历指定目录,对每一个文件进行require()
这里也是利用了这个包去实现的。具体实现以下:
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
去获取路径,那么两者有什么区别呢?
NodeJs
中process.cwd()
与__dirname
的区别
process.cwd()
是当前执行node
命令时候的文件夹地址 ——工做目录,保证了文件在不一样的目录下执行时,路径始终不变
__dirname
是被执行的js
文件的地址 ——文件所在目录
app.js
中加载这个方法便可。const app = new Koa() InitManager.initLoadRouters(app)
app/api
下建立相应的接口文件便可,如home.js
咨询请加微信:轻撩便可。