摘要:前言之前對(duì)的整體設(shè)計(jì)有過自己的理解,在中方便的插件機(jī)制也是這個(gè)框架的一大亮點(diǎn),本文主要就是從的插件開始,對(duì)后臺(tái)中的插件機(jī)制做一些分析和總結(jié)。插件的特點(diǎn)它包含了中間件配置框架擴(kuò)展等等。插件其余部分的運(yùn)行原理也是類似的。
前言
之前對(duì)egg.js的整體設(shè)計(jì)有過自己的理解,在egg.js中方便的插件機(jī)制也是這個(gè)框架的一大亮點(diǎn),本文主要就是從egg.js的插件開始,對(duì)node后臺(tái)中的插件機(jī)制做一些分析和總結(jié)。
插件在koa的項(xiàng)目中可以發(fā)現(xiàn)有大量的中間件的使用,常見的中間件可以用來做,鑒權(quán),請(qǐng)求的參數(shù)合并,錯(cuò)誤的統(tǒng)一處理等等。
中間件的特點(diǎn)大概總結(jié)一下就是:
會(huì)對(duì)請(qǐng)求進(jìn)行處理,并且影響在請(qǐng)求上
中間件有自己的加載順序,不同的順序可能會(huì)帶來不同的結(jié)果,整個(gè)koa形成了一個(gè)類似洋蔥圈的模型
這樣就會(huì)發(fā)現(xiàn)整個(gè)項(xiàng)目中確實(shí)有一些部分的功能不適合放到中間件中,比如與請(qǐng)求無關(guān)的功能,需要在初始化中就執(zhí)行的功能,需要管理中間件功能的功能,這個(gè)時(shí)候就需要用到插件的功能了。
egg插件的特點(diǎn):
它包含了 Service、中間件、配置、框架擴(kuò)展等等。
它沒有獨(dú)立的 Router 和 Controller。
基本上插件和一個(gè)獨(dú)立的應(yīng)用沒有多大的區(qū)別。
插件的加載前面說到了egg的插件其實(shí)可以直接看作是一個(gè)小的應(yīng)用,從目的上可以當(dāng)作是一些公共功能的egg應(yīng)用的抽象,那么這些插件究竟是如何被使用的呢?
首先是整個(gè)egg的應(yīng)用的加載,可以從源碼中看到分為了三個(gè)部分
/** * loadUnit is a directory that can be loaded by EggLoader, it has the same structure. * * The order of the loadUnits: * * 1. plugin * 2. framework * 3. app */ getLoadUnits() { const dirs = this.dirs = []; if (this.orderPlugins) { for (const plugin of this.orderPlugins) { dirs.push({ path: plugin.path, type: "plugin", }); } } // framework or egg path for (const eggPath of this.eggPaths) { dirs.push({ path: eggPath, type: "framework", }); } // application dirs.push({ path: this.options.baseDir, type: "app", }); return dirs; }
運(yùn)行的結(jié)果
[ { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-session", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-security", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-jsonp", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-onerror", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-i18n", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-watcher", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-multipart", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-development", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-schedule", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-logrotator", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-static", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-view", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-sequelize", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-view-art", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-validate", type: "plugin" }, { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg", type: "framework" }, { path: "/Users/qitmac000458/Workspace/developer", type: "app" } ]
可以認(rèn)為這每一個(gè)都是一個(gè)獨(dú)立的app,之后就是如何把這些應(yīng)用整合成一個(gè)app。那么簡(jiǎn)單的來看,只看app.js的整合吧
loadFile(filepath, ...inject) { if (!fs.existsSync(filepath)) { return null; } const ret = utils.loadFile(filepath); // function(arg1, args, ...) {} if (inject.length === 0) inject = [ this.app ]; return isFunction(ret) ? ret(...inject) : ret; } loadCustomApp() { this.getLoadUnits() .forEach(unit => this.loadFile(path.join(unit.path, "app.js"))); },
再回憶一下app.js的一般寫法,也就是
module.exports = app => { do something };
這樣插件中的每個(gè)app.js就都得已運(yùn)行,并且運(yùn)行順序也就很容易知道,是和getLoadUnits的運(yùn)行結(jié)果是一致的。插件其余部分的運(yùn)行原理也是類似的。
總結(jié)在了解了整個(gè)egg插件機(jī)制后,編寫一個(gè)插件其實(shí)就變得很容易了,或者說后面可以從業(yè)務(wù)代碼中直接沉淀出一整個(gè)功能作為一個(gè)插件。
egg的插件的加載幾乎是復(fù)用了整個(gè)loader,將插件的功能于原本app的業(yè)務(wù)功能實(shí)現(xiàn)了解耦,而又保持了一個(gè)egg微應(yīng)用的整體結(jié)構(gòu),這塊的設(shè)計(jì)也是很值得學(xué)習(xí)的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93341.html
摘要:項(xiàng)目擴(kuò)展自定義日志中間件封裝好之后,在實(shí)際項(xiàng)目應(yīng)用中我們還需要一步操作,提供了框架擴(kuò)展功能,包含五項(xiàng),可以對(duì)這幾項(xiàng)進(jìn)行自定義擴(kuò)展,對(duì)于日志因?yàn)槊看稳罩居涗浳覀冃枰涗洰?dāng)前請(qǐng)求攜帶的做一個(gè)鏈路追蹤,需要用到是的請(qǐng)求上下文擴(kuò)展項(xiàng)。 快速導(dǎo)航 [Logger-Custom] 需求背景 [Logger-Custom] 自定義日志插件開發(fā) [Logger-Custom] 項(xiàng)目擴(kuò)展 ...
摘要:是阿里推出的基于的開發(fā)框架,今天抽空體驗(yàn)了下,按官方教程做一個(gè)。用于解析用戶的輸入,處理后返回相應(yīng)的結(jié)果,具體參見。用于編寫業(yè)務(wù)邏輯層,可選,建議使用,具體參見。和用于自定義啟動(dòng)時(shí)的初始化工作,可選,具體參見啟動(dòng)自定義。 egg.js是阿里推出的基于koa的node開發(fā)框架,今天抽空體驗(yàn)了下,按官方教程做一個(gè)Hacker News。其實(shí)官方有腳手架提供,但是這次我們不用。 開始之前,我...
摘要:項(xiàng)目都很小,但為了進(jìn)一步了解,特意選擇了作為框架基礎(chǔ)開發(fā)后端服務(wù)。能將請(qǐng)求限制在同源網(wǎng)站,即只有擁有專有令牌的網(wǎng)站發(fā)送請(qǐng)求才會(huì)正確響應(yīng)。項(xiàng)目生產(chǎn)靜默部署,啟動(dòng)使用,停止使用。不足工具函數(shù)的訪問需要自己手動(dòng)添加擴(kuò)展另沒有寫測(cè)試,希望下次補(bǔ)上。 前言 這段時(shí)間,用Eggjs作為后端服務(wù)框架開發(fā)了幾個(gè)項(xiàng)目。項(xiàng)目都很小,但為了進(jìn)一步了解Eggjs,特意選擇了Eggjs作為框架基礎(chǔ)開發(fā)后端服務(wù)。...
摘要:如果需要在構(gòu)造函數(shù)做一些處理,一定要有這句話,才能保證后面的使用。文件夾里面存放工具類引用拿到內(nèi)置對(duì)象也就是進(jìn)入這個(gè)文件頁面渲染使用的是頁面模板在里面添加添加渲染 egg.js是什么 是一個(gè)node.js的后臺(tái)web框架,類似的還有express,koa 優(yōu)勢(shì):規(guī)范、插件機(jī)制Egg.js約定了一套代碼目錄結(jié)構(gòu)(配置config、路由router、擴(kuò)展extend、中間件middlewa...
閱讀 5099·2021-11-25 09:43
閱讀 1702·2021-10-27 14:18
閱讀 1066·2021-09-22 16:03
閱讀 1363·2019-08-30 13:19
閱讀 1584·2019-08-30 11:15
閱讀 1659·2019-08-26 14:04
閱讀 3135·2019-08-23 18:40
閱讀 1175·2019-08-23 18:17