这篇文章给大家介绍Egg.js定制业务Web框架扩展的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
谈到Node.js Web开发,你会想到的是什么?
首先是框架选型:Express、Koa、NestJS、EggJS等,需要从繁多的框架中选择一个适合团队的。
框架选好之后,需要初始化项目,安装依赖、插件、中间件、配置常见库;
假如再一次做新项目,还得从头初始化再来一次。好一点的可以封装一个骨架,从骨架中生成新项目,周而复始。
我们先想想这样做的缺陷是什么?
如果没有骨架,团队成员技术选型不一致,变成遍地开花;每个新项目维护都有学习成本。
即便有骨架,发生一些升级也需要每个项目都统一升级一遍,后续也会导致不统一。
基于以上的原因,我们考虑的解法是:基于通用框架封装一个统一的业务框架,将团队用到的公共功能下沉到业务框架中。
业务框架封装
框架选型
主流的Web框架选型主要分为两大流派,基于Express 和 基于Koa,他们都是由同一团队打造。Express和Koa在设计思路上的区别在于:
Express本身功能内置了很多中间件,集成度高,使用省心,上手即用;
Koa使用精简的内核,更轻量,使用需要使用者做技术选型按需搭建积木;
基于以上的设计思路上的差别,基于对灵活配置型的考虑,笔者选择了 基于Koa 的 流派。但他们都太底层,对于搭建企业级业务框架还需要做较多定制。
Egg.js是什么
基于上述的诉求,最后小编选择了Egg.js。
Egg.js地址:https://eggjs.org/zh-cn/
Egg.js是阿里开源的基于Koa2企业级Node.JS框架,其核心设计就是希望基于Egg.js孕育出更多上层框架。
引用官网的一句话
我们深知企业级应用在追求规范和共建的同时,还需要考虑如何平衡不同团队之间的差异,求同存异。所以我们没有选择社区常见框架的大集市模式(集成如数据库、模板引擎、前端框架等功能),而是专注于提供 Web 开发的核心功能和一套灵活可扩展的插件机制。「——官网」
定制目标
在开始定制业务框架前,我们先设定一下需要定制的目标。
扩展Controller,添加API成功/失败返回结果函数;
设置默认模板引擎为 pug;
扩展ctx,添加util, 将dayjs作为统一日期处理库;
编码
如果对Egg.js不太熟悉,建议可以先学习下Egg.js的基本使用。
框架初始化
通过以下命令,初始化项目。其中 --type=framework 表示框架骨架
villa-framework为框架名和项目文件夹名
$ npm init egg --type=framework villa-framework
以下是初始化出来的目录
villa-framework ├── app │ ├── extend │ └── service ├── config │ ├── config.default.js │ └── plugin.js ├── lib │ └── framework.js ├── test │ ├── fixtures │ └── framework.test.js ├── README.md ├── index.js └── package.json
其中app、config目录基本跟正常的Egg.js应用无差异,但增加了framework.js文件,对应用进行扩展。
// lib/framework.js 'use strict'; const path = require('path'); const egg = require('egg'); const EGG_PATH = Symbol.for('egg#eggPath'); class Application extends egg.Application { get [EGG_PATH]() { return path.dirname(__dirname); } } class Agent extends egg.Agent { get [EGG_PATH]() { return path.dirname(__dirname); } } module.exports = Object.assign(egg, { Application, Agent, });
扩展Controller,添加成功失败返回结果处理函数
// 以下是Egg.js Controller使用的代码 const Controller = require('egg').Controller; // 未来修改为 const Controller = require('villa-framework').Controller;
由上面源码我们知道,Controller来自egg对象,因此我们只需要替换为我们定义的Controller即可。
// lib/framework.js 增加 class Controller extends egg.Controller { ok(data) { this.ctx.body = { success: true, data, }; } fail(message, code) { this.ctx.body = { code, message, }; } } // 导出增加Controller module.exports = Object.assign(egg, { Application, Agent, Controller, });
这样用户使用的Controller就变成框架的Controller。
模板引擎设置为 pug
安装依赖
$ npm i --save egg-view-pug
启动插件
// config/plugin.js exports.pug = { enable: true, package: 'egg-view-pug', };
设置view渲染
// config/config.default.js config.view = { mapping: { '.pug': 'pug', }, };
这样应用框架就不需要再单独安装配置,默认拥有pug模板引擎能力。不同的业务可以根据自己的需求,默认加载并配置一些默认插件。
扩展ctx.util, 将dayjs作为统一日期处理库
安装依赖
$ npm i --save dayjs
app文件夹中新建util文件,添加day.js并导出
// app/util/dayjs.js 'use strict'; const dayjs = require('dayjs'); exports.dayjs = dayjs;
因为新增的util不会默认加载,配置自定义加载器。
// config/config.default.js config.customLoader = { // 定义在 app 上的属性名 app.util util: { directory: 'app/util', // 如果是 ctx 则使用 loadToContext inject: 'ctx', // 是否加载框架和插件的目录 loadunit: true, }, };
这样框架就会默认加载util。
应用创建
接下来我们创建应用,使用上面的villa-framework
初始化应用
$ npm init egg --type=simple villa-project $ npm i --save villa-framework $ npm i $ npm run dev
将Egg.js上层框架修改为villa-framework
package.json中egg字段中添加 "framework": "villa-framework"
"egg": { "framework": "villa-framework", },
修改controller进行测试
'use strict'; // app/controller/home.js const Controller = require('villa-framework').Controller; class HomeController extends Controller { async index() { const { dayjs } = this.ctx.util.dayjs; const now = dayjs().format('YYYY-MM-DD HH:mm:ss'); await this.ctx.render('index.pug', { now }); } renderOk() { this.ok('hi, egg'); } renderFail() { this.fail('fail', 200); } } module.exports = HomeController;
添加路由
'use strict'; // app/router.js module.exports = (app) => { const { router, controller } = app; router.get('/', controller.home.index); router.get('/ok', controller.home.renderOk); router.get('/fail', controller.home.renderFail); };
添加首页模板
在app中创建view文件夹,并添加index.pug
html head title hello world body p hello world p #{now}
启动后即可看到演示的结果。
打开 http:///127.0.0.1:7001
打开 http:///127.0.0.1:7001/ok
打开 http:///127.0.0.1:7001/fail
以上通过实现扩展Controller,扩展ctx,以及添加默认插件,演示了对Egg.js基本的扩展。
当然对于一个完整的业务框架,还缺少很多东西,但以上提供了一种对Egg.js的扩展的思路,希望可以为你扩展提供思路。
关于Egg.js定制业务Web框架扩展的示例分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。