mark一下我接触过的插件设计

  • 简单列举自己用到的类库,搜集一下大家构建插件系统的区别。

因为是对以前反推,所以可能顺序不代表我对类库的了解时间。

本文纯原创,希望在转载时需带上原链接。

Vue框架

Vue中使用use方法进行注册插件

利用install方法进行注册。

其原理还是在扩展Vue构造函数。

所以需要在new Vue以前完成注册。

Vue.use = function (plugin: Function | Object) {
    // 不重复注册
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }

核心源码。

官网🌰

MyPlugin.install = function (Vue, options) {
  // 1. 添加全局方法或 property
  Vue.myGlobalMethod = function () {
    // 逻辑...
  }

  // 2. 添加全局资源
  Vue.directive('my-directive', {
    bind (el, binding, vnode, oldVnode) {
      // 逻辑...
    }
    ...
  })

  // 3. 注入组件选项
  Vue.mixin({
    created: function () {
      // 逻辑...
    }
    ...
  })

  // 4. 添加实例方法
  Vue.prototype.$myMethod = function (methodOptions) {
    // 逻辑...
  }
}

Redux插件机制

Redux提及的是中间件。

约等于

f => g => x => 
middlewareAPI => dispatch => action => mutaion

核心实现关键代码

export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = () => {
      throw new Error(
        `Dispatching while constructing your middleware is not allowed. ` +
          `Other middleware would not be applied to this dispatch.`
      )
    }

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

中间件中使用middlewareAPI的dispatch是包装后的dispatch,使用第二个dispatch是未包装的dispatch

贴图一下redux-thunk的中间件

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => (next) => (action) => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

当调用第一个解构的dispatch时,则继续调用下一个中间件的dispatch.调用next时候则调用原先的dispatch

jquery插件

JQ插件跟Vue插件很像,都是挂载JQ原型上。一般用于挂载一些通用的方法功能。

用的不多,以前开发类似jq的zepto倒是看过一些插件,实现机制几乎相似。

贴一些jq插件的片段用作记录

(function( $ ) {
    $.fn.myPlugin = function() {

        // 插件的具体内容放在这里

    };
})( jQuery );

gulp 插件

https://github.com/ZWkang/gulp-headnote/blob/master/index.js

这里有一个自己很多年前的一个gulp简单插件的实现。

gulp在用一个虚拟的文件流 Vinyl 来做整个gulp的运行时,利用transformer 转换流来做这个任务流的管理。

也就是插件实际上就是在做一个文件转换的过程,其充当的功能单一也单向。

所以一般用gulp的时候我们都是各个任务做任务流,很少像webpack一样基于整个网状图谱去做操作。

'use strict';
var through = require('through2');

module.exports = function (options,hash) {
    return through.obj(function (file, enc, cb) {
            cb();
    });
};

还需要在插件内部自行去判断文件的类型是stream of buffer,从而根据不同的文件流格式去做整合

当然插件还需要遵循一些基本原则,例如gulp-开头之类的。

babel 插件

webpack 插件

eslint 插件

eslint 插件更多的是指自定义语法格式检测的实现。

当代码转化为抽象语法树,eslint更多关注在代码格式以及实际规范需求。

eslint插件的编写有两个重要的部分

  1. rule 规则
  2. fix 函数

Contact Me

all encode by base64

  • Email: a2FuZzk1NjMwQGdtYWlsLmNvbQ==
  • QQ: OTA3NzQ3ODc0QHFxLmNvbQo=
  • twitter: d2thbmdfelpa

    Email: a2FuZzk1NjMwQGdtYWlsLmNvbQ=

    by zwkang

    original url: https://zwkang.com

转载需注明出处与作者

否则将被视为侵权

Reprinting must indicate the source and author

Otherwise it will be regarded as infringement

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注