Skip to content

Commit

Permalink
feat: allow plugin to be installed in localVue (#497)
Browse files Browse the repository at this point in the history
* feat: allow plugin to be installed in localVue

* chore: fix tests

* chore: cr fixes

* chore: fix tests and copy version

* Update test/use.spec.ts

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>

* Update test/use.spec.ts

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>

* chore: fix ts

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
pikax and antfu authored Sep 12, 2020
1 parent 255dc72 commit 07be9d7
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 10 deletions.
18 changes: 9 additions & 9 deletions src/install.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import type { VueConstructor } from 'vue'
import { AnyObject } from './types/basic'
import { hasSymbol, hasOwn, isPlainObject, assert } from './utils'
import { hasSymbol, hasOwn, isPlainObject, assert, warn } from './utils'
import { isRef, markReactive } from './reactivity'
import {
setVueConstructor,
isVueRegistered,
isPluginInstalled,
} from './runtimeContext'
import { setVueConstructor, isVueRegistered } from './runtimeContext'
import { mixin } from './mixin'

/**
Expand Down Expand Up @@ -44,7 +40,7 @@ function mergeData(from: AnyObject, to: AnyObject): Object {
}

export function install(Vue: VueConstructor) {
if (isPluginInstalled() || isVueRegistered(Vue)) {
if (isVueRegistered(Vue)) {
if (__DEV__) {
assert(
false,
Expand All @@ -55,8 +51,12 @@ export function install(Vue: VueConstructor) {
}

if (__DEV__) {
if (Vue.version[0] !== '2' || Vue.version[1] !== '.') {
assert(false, `only works with Vue 2, v${Vue.version} found.`)
if (Vue.version) {
if (Vue.version[0] !== '2' || Vue.version[1] !== '.') {
assert(false, `only works with Vue 2, v${Vue.version} found.`)
}
} else {
warn('Vue version not found')
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/runtimeContext.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { VueConstructor } from 'vue'
import { ComponentInstance } from './component'
import { assert, hasOwn } from './utils'
import { assert, hasOwn, warn } from './utils'

let vueConstructor: VueConstructor | null = null
let currentInstance: ComponentInstance | null = null
Expand All @@ -27,6 +27,9 @@ export function getVueConstructor(): VueConstructor {
}

export function setVueConstructor(Vue: VueConstructor) {
if (__DEV__ && vueConstructor) {
warn('Another instance of vue installed')
}
vueConstructor = Vue
Object.defineProperty(Vue, PluginInstalledFlag, {
configurable: true,
Expand Down
33 changes: 33 additions & 0 deletions test/helpers/create-local-vue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Vue, { VueConstructor } from 'vue'

// based on https://github.com/vuejs/vue-test-utils/blob/dev/packages/test-utils/src/create-local-vue.js

export function createLocalVue(_Vue: VueConstructor = Vue) {
const instance = _Vue.extend()

Object.keys(_Vue).forEach((key) => {
// @ts-ignore
instance[key] = _Vue[key]
})

// @ts-ignore
if (instance._installedPlugins && instance._installedPlugins.length) {
// @ts-ignore
instance._installedPlugins.length = 0
}

instance.config = _Vue.config

const use = instance.use
//@ts-ignore
instance.use = (plugin, ...rest) => {
if (plugin.installed === true) {
plugin.installed = false
}
if (plugin.install && plugin.install.installed === true) {
plugin.install.installed = false
}
use.call(instance, plugin, ...rest)
}
return instance
}
35 changes: 35 additions & 0 deletions test/use.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import CompositionApi from '../src'
import { createLocalVue } from './helpers/create-local-vue'
import { mockWarn } from './helpers'

describe('use', () => {
mockWarn(true)

it('should allow install in multiple vue', () => {
const localVueOne = createLocalVue()
localVueOne.use(CompositionApi)

const localVueTwo = createLocalVue()
localVueTwo.use(CompositionApi)

expect('Another instance of vue installed').toHaveBeenWarned()
})

it('should warn installing multiple times', () => {
const localVueOne = createLocalVue()
localVueOne.use(CompositionApi)

expect(() => {
// vue prevents the same plugin of being installed, this will create a new plugin instance
localVueOne.use({
install(v) {
CompositionApi.install(v)
},
})
}).toThrowError(
'already installed. Vue.use(VueCompositionAPI) should be called only once.'
)

expect('Another instance of vue installed').toHaveBeenWarned()
})
})

0 comments on commit 07be9d7

Please sign in to comment.