【转】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 被更多人使用和喜欢。

相关文章
相关标签/搜索