node路由去中心化

简介

node 读取文件目录实现去中心化管理路由node

背景

最近写node项目发现路由太多,手动require不符合程序员的气质。为了偷懒只能写一段代码自动导入了。程序员

目录结构

│─app.js // 入口文件
│─router  // 路由文件夹
│    │─router.js  // 路由集中
│    ├─V1   //版本文件
│    │ └─test.js  // 路由
│    └─V2
│       └─test.js
│─utils
    └─requireContext.js // 工具函数
复制代码

app.js

// app.js 代码
    const Koa = require('koa')
    const routes = require('./router/router.js')
    const app = new Koa()
    // 挂载路由
    app.use(routes)
    app.listen(3000)
复制代码

router.js

// router/router.js 做为路由的集中地
    const path = require('path')
    const compose  = require('koa-compose')
    const requireContext = require('../utils/requireContext.js')
    
    // 原来的写法
    /* const routes = compose([ //须要将全部的路由导入进来 require('./V1/test.js').routes(), require('./V1/test.js').routes(), ]) */
    
    //如今的写法 新曾路由文件不再用手动导入了
    // 参数1 文件路径
    // 参数2 正则 这里是 不是router.js结尾的全部js 
    // 参数3 递归子目录
    let files = requireContext(path.resolve(__dirname, './'), /(?<!router)\.js$/, true) console.log(files); const routes = compose(files.map(item => require(item).routes())) // 导出路由中间件集合 module.exports = routes 复制代码

test.js

// router/V1/test.js router/V2/test.js 
    const Router = require('koa-router')
    const router = new Router()
    router.prefix('/V2')
    router.get('/test', (ctx, next) => {
    	ctx.body = 'hello'
    })
    // 导出路由
    module.exports = router
复制代码

requireContext.js

// 文件加载去中心化
    const fs = require('fs')
    const path = require('path')
    /** * @param {String} filePath 目录绝对路径 * @param {Regexp} filters 过滤器 * @param {Boolean} deep 是否遍历子目录 * @returns {Array} */
    function requireContext(filePath, filters, deep) {
    	// 文件直接退出
    	if (fs.statSync(filePath).isFile()) {
    		return [filePath]
    	}
    
    	// 过滤器不是正则
    	if (filters && !(filters instanceof RegExp)) {
    		throw new Error('filters must Regexp')
    	}
    
    	let filesArray = []
    	findFile(filePath, deep, filesArray)
    
    	return filters ? filesArray.filter(item => filters.test(item)) : filesArray
    }

    function findFile(filePath, deep, filesArray) {
    	let files = fs.readdirSync(filePath)
    
    	files.forEach(item => {
    		let fPath = path.resolve(filePath, item)
    
    		if (fs.statSync(fPath).isFile()) {
    			filesArray.push(fPath)
    		} else if (deep) {
    			findFile(fPath, deep, filesArray)
    		}
    
    	})
    }

    module.exports = requireContext

复制代码