【轉】nodejs 如何實現一個簡單的插件擴展

爲何須要插件擴展?

  • 模塊化思想

任何一個易用的系統都強調易用,易維護,模塊化是 nodejs 的核心思想(顯然並非 nodejs 首先提出的); nodejs 有不少優秀的 package 都支持插件式開發: hexo(很是流行的靜態博客生成工具),egg(ali 團隊推出的企業級開發框架),etc...php

固然模塊化不只僅限於使用插件化的方式;還有 node web 開發中很是常見的中間件模式。java

總之,不管是 oop 、中間件、插件化這些設計模式都是爲了更加解耦、更加抽象、更加易讀、易用、易維護。node

  • 擴展更加便捷

好的設計模式能夠作到不須要對現有的系統代碼作任何修改,對現有代碼無侵入的狀況下作到功能拓展。插件機制就是一種很常見的設計模式,能夠用最小的成本知足大部分的應用場景。web

  • 核心代碼更純粹

插件能夠隨時添加,任意添加,對已封裝的核心代碼沒有任何改變,核心代碼更加純粹,保持最精簡的狀態,極大程度的避免了快速迭代過程當中形成核心崩潰的狀況。設計模式

如何實現插件擴展機制?

  • 反射機制

java ,.net 等 oop 語言都有反射機制,便可以根據類名動態加載類的信息到內存或虛擬機中,完成對象的建立。這種反射機制是如今流行的主流框架的基本實現手段,它們之因此如此優秀於靈活,就是由於這種機制提供了更自由的擴展於變化;讓 coder 更關注業務。api

  • require

nodejs 並無反射機制,由於它自己是非編譯型的,爲了能有更好的擴展, nodejs 設計了 require 機制,能夠經過 require 函數自由的加載須要的模塊,某種意義上說:hexo

require 就是 nodejs 的反射機制!框架

可是 nodejs 在不斷更新,慢慢會出現更好的特性,必然也會實現其反射機制。不過就目前來看, require 已經能夠知足咱們實現插件化開發了。模塊化

  • hook

hook 即鉤子,是一種在 php 系統中使用較爲多見的概念,好比很是著名的博客系統: wordpress ,就有很是多豐富的插件;而插件的基礎就是 hook !假設一個模型:wordpress

// code list 1:
var core = { 
 run: function(){
   console.log('hi there~');
 }
};

core.run();
// hi there~

針對這樣的設計,咱們沒法完成任何事情,想要在 run 以後執行一些其它的操做,只能修改它的代碼好比:

// code list 2:
var core = { 
 run: function(){
   console.log('hi there~');
   console.log('an other greeting~');
 }
};

core.run();
// hi there~
// an other greeting~

這樣的設計沒法知足動態的需求,自己的核心代碼也沒法進行封裝,由於隨時須要修改它。

下面進入正文:

// code list 3:
var core = {};	//初始化
core.hooks = {};	//定義鉤子集合

/*添加鉤子的函數,這裏是重點*/
/*鉤子名,鉤子函數*/
/*將一個函數添加到 core 對象的鉤子集合中*/
core.addHook = function(hookName, hookFunction){
  var hookList = core.hooks[hookName];
  if(hookList){
    hookList.push(hookFunction);
  }else{
    hookList = [ hookFunction ];
  }
  core.hooks[hookName] = hookList;
};

/*執行鉤子集合中的鉤子函數*/
core.runHook = function(hookName){
  var hookList = core.hooks[hookName];
  if(hookList){
    for(var i = 0 ; i < hookList.length ; i++){
      hookList[i]();
    }
  }
};

/*核心入口函數*/
core.run = function(){
  core.runHook('before_run');
  console.log('hi there~');
  core.runHook('after_run');
};

core.run();
// hi there~

/*固然此時,寫了這麼多代碼,也只是和 code list 1 實現的功能同樣*/

重點來了:

若是咱們想實現 code list 2 的功能,咱們彷佛根本不須要修改 core.run 的代碼:

// code list 4:

code.addHook('after_run', function(){
  console.log('an other greeting~');
});

code.run();
// hi there~
// an other greeting~

簡單的添加一個 hook 函數就能夠實現 code list 2 實現的功能了,固然咱們還能在這個基礎上實現更多。 而這個就是一個簡單的插件化開發模型;在此基礎上不斷的提升核心代碼的健壯和容錯性就能夠將核心代碼進行封裝發佈,提供豐富的鉤子和 api 供插件開發者實現更多優秀的擴展。

總結

一個 nodejs 模塊儘可能精簡,保持較小的體積,可讓它更輕便,優雅,插件化開發可讓你的 package 被更多人使用和喜歡。

相關文章
相關標籤/搜索