lbwa / set.sh-stale

✍A place which is used to share my programming experiences in Chinese. 一个分享代码经历的地方。
https://set.sh
0 stars 0 forks source link

将依赖作为缓存对象来实现插件开发,避免直接引入依赖 #24

Open lbwa opened 5 years ago

lbwa commented 5 years ago

vue-router

vue-rotuer 源码中,vuejs 的插件开发是依赖通过插件 install 方法 动态 传入的 Vue 对象。这是为了避免单独 import Vue 将导致插件直接依赖 Vuejs,进而导致 package 包含 Vuejs,即插件体积增大。

// src/index.js
import { install } from './install'

export default class VueRouter {
  // ...
}
// 定义插件的 install 方法,在作为模块引入插件时,必须调用 Vue.use(VueRouter) 来向 install 方法动
// 态传入 Vue 对象,使得插件可以使用 Vue 对象
VueRouter.install = install

// 全局环境自动调用 Vue.use(VueRouter)
if (inBrowser && window.Vue) {
  window.Vue.use(VueRouter)
}

通过在插件的 install 模块中建立一个缓存容器来缓存作为参数被传入的 Vue 对象。此时, Vue 是作为参数 动态 传入,并不是作为函数中的静态变量而存在。那么仅在调用 install 方法时, Vue 对象才会被传入。那么也就避免了在插件 install 函数中直接依赖 Vue 对象。同时也并不影响插件在被调用时对 Vue 对象的依赖。

// src/install.js

// 缓存容器,export 之后可用于其他非 install.js 的模块调用 Vue 对象,如 src/history/base.js
export let  _Vue

// 通过参数形式来避免 Vue 被 install 方法直接依赖,此举可避免插件 package 打包 Vue
export function install (Vue) {
  if (install.installed && _Vue === Vue) return
  install.installed = true

  _Vue = Vue
  // ...
}

总结

纵观 vuejs 的插件开发原理,无论是在以后自己开发 vuejs 插件还是其他库,都可利用 将依赖转变为参数 的方式来避免 package 体积增大。即避免了模块对其他模块的直接依赖。这个思路个人认为比较适合插件开发,因为它的依赖动态引入原理极大地限制了插件的 dependcies

Reference

lbwa commented 5 years ago

此举本质上与函数式编程中的 dependency injection 概念相同,它用于显式地指明函数的依赖变量。但 Vue.js 的插件机制重点 不仅仅 在于保持函数式编程中的函数 纯洁性,而是更加侧重于对于函数内部变量的解耦,即动态引入变量。

References