评论

feflow 插件实现原理

介绍 feflow 的插件机制,详细的描述如何注册、实现和使用插件的全过程。

最近在着手接入和推进研发的规范化、流程化,使得团队开发风格更加统一,提升研发质量与效率。在接入的过程中,选择 feflow 与 现有的相关流程相结合管理脚手架升级和项目初始化,后续考虑开发或者使用插件处理更多业务开发流程。了解插件实现原理,有利于后续插件开发和使用;学习其设计方式,对其他项目开发大有裨益。

feflow 是前端研发规范化和流程化工具,常见的内置指令有: init、 dev、build、deploy等,从初始化到构建都提供内置指令,如若需要额外指令实现特定功能,就需要自定定义插件;本质上feflow是一个插件加载工具,可以让开发者开发适用于业务的插件。本文主要介绍 feflow 是如何进行插件注册、加载和使用。

一、插件注册

feflow 作为一个命令行执行工具,自然而然地支持命令注册,无论是内置指令还是自定义插件,都需要注册相关命令的。首先看一下如何注册指令,以 feflow-plugin-example 为例,其代码如下:

feflow.cmd.register('add', '加法运算器', function(args) {
   // do something
    add(args._);
});

注册指令需要的参数如下:

  • name 必填,指令名称
  • desc 必填,阐述相关指令的作用
  • options 可选,函数相关可选项
  • fn 必填,指令调用的回调函数

指令注册是 feflow 中 Commond 对象来实现的,Commond 中定义 store 对象,其会存储相关指令,并把指令和指令相关功能做一一映射。关键代码如下:

  funciton register(name, desc, options, fn) {
    //... format parameter

    const c = this.store[name.toLowerCase()] = fn;
    c.options = options;
    c.desc = desc;
    //provide an alias for the instruction.
    //feflow version is equal to feflow v(ersion)
    this.alias = abbrev(Object.keys(this.store));
  }

二、插件加载

插件注册安装之后,都会存储在 feflow 安装的 node_modules目录下,在 feflow 进行初始化的时候,首先会读取以feflow-plugin-开头的文件夹,然后进行插件动态加载。

2.1 模块初始化
动态加载是模拟 Node 模块加载方式的实现,首先会初始化 module 模块。其中会包含模块相关路径、文件名称等相关信息。在进行模块加载时会进行路径查找,即 module.paths。

const module = new Module(path);
module.filename = path;
module.paths = Module._nodeModulePaths(path);

2.2 编译调用
编译执行时首先会通过fs.readFile去获取对应的文件内容,接下来重点看一下是如何编译调用的,代码片段如下:

script = '(function(exports, require, module, __filename, __dirname, feflow){' +
script + '});'; //(1)

const fn = vm.runInThisContext(script, path); //(2)

return fn(module.exports, require, module, path, pathFn.dirname(path), self); //(3)

首先看到是对原始内容进行封装(标注1),会传入CommonJS 相关规范实现的 exports, require, module, _filename, _dirname 以及注入的自定义变量 feflow。经过封装的内容如下:

(function (exports, require, module, __filename, __dirname) { 
	//原始内容
});

经过包装后返回的字符串,会作为 vm.runInThisContext() 方法的输入参数(标注2)。vm 模块简单的来说就是用来做沙箱环境执行代码,对代码的上下文环境做隔离。vm.runInThisContext 类似 eval,不同的是生成的代码运行时可以访问外部的 global 对象,但是不能访问其他变量。接下来会传入当前 feflow 实例,调用自定义指令的注册(标注3)。

三、插件使用

在插件使用前确保已经全局安装 feflow-cli:

npm install -g feflow-cli

对于插件使用分两种情况:
(1) 插件开发之后发布到 NPM 上或者 NPM 私有仓库
(2) 插件未发布
下面分别详细介绍使用步骤。

插件已发布

1.插件进行安装:

feflow install feflow-plugin-example

2.调用对应指令:

feflow add 1 2

插件未发布

1.在插件目录下 npm link:

cd feflow-plugin-example
npm link

2.到 feflow 安装目录 .feflow 中安装

npm link feflow-plugin-example

3.编辑 .feflow/package.json 文件,加入依赖

dependencies: {
    //...
    "feflow-plugin-example": "1.0.0"
}

修改完成之后就可以进行调用。

最后一次编辑于  03-30  
点赞 2
收藏
评论