分享个人 Full-Stack JavaScript 项目开发经验
在 koa2 框架中,路由通过 koa-router 中间件实现。它允许在不同路由路径下添加中间件和最终的响应回调函数。这个响应回调函数即相当于程序的控制器层。在数目繁多的控制器下,通过简单的 require 方式导入控制器是困难的。下面介绍如何更好地实现控制器的导入。
在小程序的项目开发中,官方的 node.js 版本 demo 是通过目录和文件的递归遍历把各个控制器的 require('absolute_path') 映射到一个导出对象的属性中,从而实现控制器的统一导出的。下面分享它的实现方式。
使用个控制器目录专门存放程序的控制器:
controllers/
├── part1/
├ ├── getTopic.js
├ └── ......
├── 其它模块/
├ └── ......
├── ......
└── index.js
getTopic.js:
module.exports = async (ctx, next) => {
//.....
};
index.js 作为所有控制器的导出文件:
const _ = require('lodash');
const fs = require('fs');
const path = require('path');
/**
* 映射 d 目录下的目录和文件为对象
*/
const mapDir = d => {
const tree = {};
const [dirs, files] = _.partition(
fs.readdirSync(d),
p => fs.statSync(path.join(d, p)).isDirectory()
);
// 递归映射目录
dirs.forEach(dir => {
tree[dir] = mapDir(path.join(d, dir));
});
// 映射当前目录的文件
files.forEach(file => {
// 判断文件扩展名
if (path.extname(file) === '.js') {
// 使用文件目录的最后一部分并去除 .js 分隔符作为属性名称
tree[path.basename(file, '.js')] = require(path.join(d, file));
}
});
return tree;
};
// 映射当前执行 index.js 的绝对路径下的目录和文件为对象
module.exports = mapDir(path.join(__dirname));
其中 lodash 模块需要单独安装:
yarn add lodash
最后在路由入口 routes/index.js 中,我们就可以这样导入控制器:
const router = require('koa-router')();
const controllers = require('../controllers');
router.get('/', controllers.part1.getTopic);
通过这种方式,可以减少了很多不必要的 require() 代码,但这亦失去了编辑器的路径输入提示。所以控制器命名时,应该容易理解、意义明确。