5

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

 3 years ago
source link: https://zwkang.com/?p=866
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
  • 简单列举自己用到的类库,搜集一下大家构建插件系统的区别。

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

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

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

转载需注明出处与作者

否则将被视为侵权

Reprinting must indicate the source and author

Otherwise it will be regarded as infringement

Comments

发表评论 取消回复

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

评论

姓名 *

电子邮件 *

站点

在此浏览器中保存我的名字、电邮和网站。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK