大家好,我是洛竹,那个写《Deno从入门到跑路》和《基于 Deno 构建 HTTP Server 实践指南》的作者,本来入手Deno只是为了白嫖掘金的大礼包,为此还挑战了零基础一天入门Deno。但是Deno真香,前后又花了一周的业余时间学习了MongoDB写出了一篇自认很完整的 HTTP Server 实践指南(后端同学轻喷)。
本文是一篇介绍我如何开发了一款Deno插件并发布到Deno官方插件库的。插件的名字叫Duck,是一款自动扫描controller层并注册路由的小工具。如何使用这个插件请有需要的同学点击logo直达:
项目结构
这个项目诞生的因为写《基于 Deno 构建 HTTP Server 实践指南》时,为了实现自动扫描controller的功能。借鉴了廖雪峰大佬关于koa的自动扫描controller,除了使用的语言不一样,实现细节和思路上也不太一样。
./
├── LICENSE
├── README.md
├── addAbcControllers.ts
├── addOakControllers.ts
├── addServestControllers.ts
├── mod.ts
└── test
├── abc
│ ├── controllers
│ │ └── helloworld.ts
│ └── server.ts
├── oak
│ ├── controllers
│ │ └── helloworld.ts
│ └── server.ts
└── servest
├── controllers
│ └── helloworld.ts
└── server.ts
mod.ts:Deno官方推荐的插件入口文件test:一些测试的demoadd***Controllers.ts:兼容的常见的Http Server中间件插件,自动判断,不需要用户传参数。
实现过程
自动扫描controller
注意:以下是代码片段,源码请点击开头的那只鸭子查看。
...
const realPath = Deno.realPathSync(dir);
...
for (const dirEntry of Deno.readDirSync(dir)) {
if (dirEntry.name.endsWith(".ts") || dirEntry.name.endsWith(".js")) {
const controller = await import(`file://${realPath}/${dirEntry.name}`);
const method = controller.method || "get";
const api = controller.api ||
dirEntry.name.replace(/(.*\/)*([^.]+).*/ig, "$2");
router[method](`/${api}`, controller.default);
}
}
- 根据用户传递的
dir获取的文件夹使用Deno.realPathSync获取真实的绝对路径,这里后边获取文件的时候用。 - 使用
Deno.readDirSync接口读取文件夹下所有的文件,这里做了校验,必须是js或ts结尾的文件才可以。 - 使用
import动态导入模块,这里有个坑就是不加file://前缀的话,实际运行会自动加https://。 - 这里假设如果controller没有导出name,自动读取文件名作为api名(这里借鉴了umijs)
- 最后动态把这个controller挂载到router上(router这个也是用户传递进来的)。
智能兼容
这个真没啥好说的,就是人工比对了这些插件带的独有的属性来识别是哪款插件的,目前支持 servest、oak、abc这三个关注度比较高的项目。
export default async function (router: any, dir: string = "controllers") {
if (router.handle) {
return await addServestControllers(router,dir);
} else if(router.middleware) {
return await addAbcControllers(router,dir);
} else {
return await addOakControllers(router,dir);
}
}
开箱友好
使用duck之后,默认会给两个路由路径,而且checkHealth这个是项目必备的接口了基本上(后端同学告诉我的)。
...
router.get("/", (ctx: any) => {
ctx.response.body = "Hello Oak!";
}).get("/checkHealth", (ctx: any) => {
ctx.response.body = "The server is health. Just do it.";
});
...
发布插件
1、打开 deno.land/x
2、点击 Add a module
3、按照下图的指引我们需要创建一个托管在GitHub的公有仓库
4、起一个好听的名字,趁早注册,不然要被 justjavac 大佬抢完了,可能是怕我这种水逼水插件吧,哈哈哈哈。
5、后边就是提示你去添加 GitHub 的 webhook,然后就发布成功了,我刚试了一下 superman 还没被注册。
最后狗头镇楼!!!
本文首发于杨俊宁的博客,创作不易,您的点赞👍是我坚持的动力!!!