自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于Egg.js定制業(yè)務(wù)Web框架(一) - 框架擴(kuò)展

開發(fā) 前端
通過實(shí)現(xiàn)擴(kuò)展Controller,擴(kuò)展ctx,以及添加默認(rèn)插件,演示了對(duì)Egg.js基本的擴(kuò)展。當(dāng)然對(duì)于一個(gè)完整的業(yè)務(wù)框架,還缺少很多東西,但以上提供了一種對(duì)Egg.js的擴(kuò)展的思路,希望可以為你擴(kuò)展提供思路。

[[398340]]

前言

談到Node.js Web開發(fā),你會(huì)想到的是什么?

  • 首先是框架選型:Express、Koa、NestJS、EggJS等,需要從繁多的框架中選擇一個(gè)適合團(tuán)隊(duì)的。
  • 框架選好之后,需要初始化項(xiàng)目,安裝依賴、插件、中間件、配置常見庫;
  • 假如再一次做新項(xiàng)目,還得從頭初始化再來一次。好一點(diǎn)的可以封裝一個(gè)骨架,從骨架中生成新項(xiàng)目,周而復(fù)始。

我們先想想這樣做的缺陷是什么?

  • 如果沒有骨架,團(tuán)隊(duì)成員技術(shù)選型不一致,變成遍地開花;每個(gè)新項(xiàng)目維護(hù)都有學(xué)習(xí)成本。
  • 即便有骨架,發(fā)生一些升級(jí)也需要每個(gè)項(xiàng)目都統(tǒng)一升級(jí)一遍,后續(xù)也會(huì)導(dǎo)致不統(tǒng)一。

基于以上的原因,我們考慮的解法是:基于通用框架封裝一個(gè)統(tǒng)一的業(yè)務(wù)框架,將團(tuán)隊(duì)用到的公共功能下沉到業(yè)務(wù)框架中。

業(yè)務(wù)框架封裝

框架選型

為了選擇合適的底層框架,小編整理了awesome-nodejs的倉庫(每個(gè)分類按github star數(shù)排序),從Web框架部分可以看到非常豐富,那么我們?nèi)绾芜x擇。

awesome-nodejs地址: https://github.com/huaize2020/awesome-nodejs/blob/main/README-zh-CN.md

主流的Web框架選型主要分為兩大流派,基于Express 和 基于Koa,他們都是由同一團(tuán)隊(duì)打造。Express和Koa在設(shè)計(jì)思路上的區(qū)別在于:

  • Express本身功能內(nèi)置了很多中間件,集成度高,使用省心,上手即用;
  • Koa使用精簡的內(nèi)核,更輕量,使用需要使用者做技術(shù)選型按需搭建積木;

基于以上的設(shè)計(jì)思路上的差別,基于對(duì)靈活配置型的考慮,筆者選擇了 基于Koa 的 流派。但他們都太底層,對(duì)于搭建企業(yè)級(jí)業(yè)務(wù)框架還需要做較多定制。

Egg.js是什么

基于上述的訴求,最后小編選擇了Egg.js。

Egg.js地址:https://eggjs.org/zh-cn/

Egg.js是阿里開源的基于Koa2企業(yè)級(jí)Node.JS框架,其核心設(shè)計(jì)就是希望基于Egg.js孕育出更多上層框架。

引用官網(wǎng)的一句話

  • 我們深知企業(yè)級(jí)應(yīng)用在追求規(guī)范和共建的同時(shí),還需要考慮如何平衡不同團(tuán)隊(duì)之間的差異,求同存異。所以我們沒有選擇社區(qū)常見框架的大集市模式(集成如數(shù)據(jù)庫、模板引擎、前端框架等功能),而是專注于提供 Web 開發(fā)的核心功能和一套靈活可擴(kuò)展的插件機(jī)制。「——官網(wǎng)」

定制目標(biāo)

在開始定制業(yè)務(wù)框架前,我們先設(shè)定一下需要定制的目標(biāo)。

  • 擴(kuò)展Controller,添加API成功/失敗返回結(jié)果函數(shù);
  • 設(shè)置默認(rèn)模板引擎為 pug;
  • 擴(kuò)展ctx,添加util, 將dayjs作為統(tǒng)一日期處理庫;

編碼

如果對(duì)Egg.js不太熟悉,建議可以先學(xué)習(xí)下Egg.js的基本使用。

框架初始化

通過以下命令,初始化項(xiàng)目。其中 --type=framework 表示框架骨架

villa-framework為框架名和項(xiàng)目文件夾名

  1. $ npm init egg --type=framework villa-framework 

以下是初始化出來的目錄

  1. villa-framework 
  2. ├── app 
  3. │   ├── extend 
  4. │   └── service 
  5. ├── config 
  6. │   ├── config.default.js 
  7. │   └── plugin.js 
  8. ├── lib 
  9. │   └── framework.js 
  10. ├── test 
  11. │   ├── fixtures 
  12. │   └── framework.test.js 
  13. ├── README.md 
  14. ├── index.js 
  15. └── package.json 

其中app、config目錄基本跟正常的Egg.js應(yīng)用無差異,但增加了framework.js文件,對(duì)應(yīng)用進(jìn)行擴(kuò)展。

  1. // lib/framework.js 
  2. 'use strict'
  3.  
  4. const path = require('path'); 
  5. const egg = require('egg'); 
  6. const EGG_PATH = Symbol.for('egg#eggPath'); 
  7.  
  8. class Application extends egg.Application { 
  9.   get [EGG_PATH]() { 
  10.     return path.dirname(__dirname); 
  11.   } 
  12.  
  13. class Agent extends egg.Agent { 
  14.   get [EGG_PATH]() { 
  15.     return path.dirname(__dirname); 
  16.   } 
  17.  
  18. module.exports = Object.assign(egg, { 
  19.   Application, 
  20.   Agent, 
  21. }); 

擴(kuò)展Controller,添加成功失敗返回結(jié)果處理函數(shù)

  1. // 以下是Egg.js Controller使用的代碼 
  2. const Controller = require('egg').Controller; 
  3.  
  4. // 未來修改為 
  5. const Controller = require('villa-framework').Controller; 

由上面源碼我們知道,Controller來自egg對(duì)象,因此我們只需要替換為我們定義的Controller即可。

  1. // lib/framework.js 增加 
  2. class Controller extends egg.Controller { 
  3.   ok(data) { 
  4.     this.ctx.body = { 
  5.       success: true
  6.       data, 
  7.     }; 
  8.   } 
  9.  
  10.   fail(message, code) { 
  11.     this.ctx.body = { 
  12.       code, 
  13.       message, 
  14.     }; 
  15.   } 
  16.  
  17. // 導(dǎo)出增加Controller 
  18. module.exports = Object.assign(egg, { 
  19.   Application, 
  20.   Agent, 
  21.   Controller, 
  22. }); 

這樣用戶使用的Controller就變成框架的Controller。

模板引擎設(shè)置為 pug

安裝依賴

  1. $ npm i --save egg-view-pug 

啟動(dòng)插件

  1. // config/plugin.js 
  2. exports.pug = { 
  3.   enable: true
  4.   package: 'egg-view-pug'
  5. }; 

設(shè)置view渲染

  1. // config/config.default.js 
  2. config.view = { 
  3.   mapping: { 
  4.     '.pug''pug'
  5.   }, 
  6. }; 

這樣應(yīng)用框架就不需要再單獨(dú)安裝配置,默認(rèn)擁有pug模板引擎能力。不同的業(yè)務(wù)可以根據(jù)自己的需求,默認(rèn)加載并配置一些默認(rèn)插件。

擴(kuò)展ctx.util, 將dayjs作為統(tǒng)一日期處理庫

安裝依賴

  1. $ npm i --save dayjs 

app文件夾中新建util文件,添加day.js并導(dǎo)出

  1. // app/util/dayjs.js 
  2. 'use strict'
  3. const dayjs = require('dayjs'); 
  4. exports.dayjs = dayjs; 

因?yàn)樾略龅膗til不會(huì)默認(rèn)加載,配置自定義加載器。

  1. // config/config.default.js 
  2. config.customLoader = { 
  3.   // 定義在 app 上的屬性名 app.util 
  4.   util: { 
  5.     directory: 'app/util'
  6.     // 如果是 ctx 則使用 loadToContext 
  7.     inject: 'ctx'
  8.     // 是否加載框架和插件的目錄 
  9.     loadunit: true
  10.   }, 
  11. }; 

這樣框架就會(huì)默認(rèn)加載util。

應(yīng)用創(chuàng)建

接下來我們創(chuàng)建應(yīng)用,使用上面的villa-framework

初始化應(yīng)用

  1. $ npm init egg --type=simple villa-project 
  2. $ npm i --save villa-framework 
  3. $ npm i 
  4. $ npm run dev 

將Egg.js上層框架修改為villa-framework

package.json中egg字段中添加 "framework": "villa-framework"

  1. "egg": { 
  2.   "framework""villa-framework"
  3. }, 

修改controller進(jìn)行測試

  1. 'use strict'
  2. // app/controller/home.js 
  3. const Controller = require('villa-framework').Controller; 
  4.  
  5. class HomeController extends Controller { 
  6.   async index() { 
  7.     const { dayjs } = this.ctx.util.dayjs; 
  8.     const now = dayjs().format('YYYY-MM-DD HH:mm:ss'); 
  9.     await this.ctx.render('index.pug', { now }); 
  10.   } 
  11.  
  12.   renderOk() { 
  13.     this.ok('hi, egg'); 
  14.   } 
  15.  
  16.   renderFail() { 
  17.     this.fail('fail', 200); 
  18.   } 
  19.  
  20. module.exports = HomeController; 

添加路由

  1. 'use strict'
  2. // app/router.js 
  3. /** 
  4.  * @param {Egg.Application} app - egg application 
  5.  */ 
  6. module.exports = (app) => { 
  7.   const { router, controller } = app; 
  8.   router.get('/', controller.home.index); 
  9.   router.get('/ok', controller.home.renderOk); 
  10.   router.get('/fail', controller.home.renderFail); 
  11. }; 

添加首頁模板

在app中創(chuàng)建view文件夾,并添加index.pug

  1. html 
  2.     head 
  3.         title hello world 
  4.     body 
  5.         p hello world 
  6.         p #{now} 

啟動(dòng)后即可看到演示的結(jié)果。

打開 http:///127.0.0.1:7001

打開 http:///127.0.0.1:7001/ok

打開 http:///127.0.0.1:7001/fail

總結(jié)

以上通過實(shí)現(xiàn)擴(kuò)展Controller,擴(kuò)展ctx,以及添加默認(rèn)插件,演示了對(duì)Egg.js基本的擴(kuò)展。

當(dāng)然對(duì)于一個(gè)完整的業(yè)務(wù)框架,還缺少很多東西,但以上提供了一種對(duì)Egg.js的擴(kuò)展的思路,希望可以為你擴(kuò)展提供思路。

當(dāng)前系列作為《基于Egg.js定制業(yè)務(wù)Web框架》系列一, 后續(xù)將持續(xù)輸出:定制IoC容器,定制注解系統(tǒng)、monorepo改造、框架CLI系列,敬請(qǐng)關(guān)注。

框架地址:https://github.com/huaize2020/blog/tree/main/projects/villa-v1/villa-framework

應(yīng)用調(diào)用地址:https://github.com/huaize2020/blog/tree/main/projects/villa-v1/villa-project

awesome-nodejs: https://github.com/huaize2020/awesome-nodejs/blob/main/README-zh-CN.md

 

責(zé)任編輯:姜華 來源: Eval Studio
相關(guān)推薦

2010-03-29 13:37:15

ibmdwJAXB

2024-03-14 08:32:37

HTMLWeb 框架PPT

2024-03-11 10:19:30

Plasmo瀏覽器Web

2019-08-29 10:58:02

Web 開發(fā)框架

2023-11-03 08:04:47

Web微前端框架

2012-03-07 14:32:41

Node.js

2009-11-12 16:17:13

.NET

2009-06-25 17:14:59

JSF框架

2012-09-26 09:46:29

ASP.NETWeb框架

2010-08-13 14:29:45

Flex框架

2010-08-05 13:50:54

Flex框架

2010-08-10 14:53:32

FlexRiawave

2023-04-27 08:23:38

JavaScriptVue.jsMVVC

2017-07-18 15:13:17

2009-06-19 09:52:46

Acegi安全框架Spring框架

2012-02-08 13:49:53

Node.js

2009-03-17 09:15:20

圖表框架CSSJavaScript

2022-05-30 09:32:07

Spring容器

2009-03-16 09:16:13

行為擴(kuò)展WCF.NET

2021-07-15 11:16:31

Spring WebWebFlux架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)