feat(runtime-vapor): implement app plugin

This commit is contained in:
三咲智子 Kevin Deng 2024-05-17 20:54:08 +08:00
parent b776f92596
commit d77c7ade77
No known key found for this signature in database
3 changed files with 88 additions and 0 deletions

View File

@ -0,0 +1,45 @@
import { type Component, type Plugin, createVaporApp, inject } from '../src'
;``
describe('api: createApp', () => {
test('use', () => {
const PluginA: Plugin = app => app.provide('foo', 1)
const PluginB: Plugin = {
install: (app, arg1, arg2) => app.provide('bar', arg1 + arg2),
}
class PluginC {
someProperty = {}
static install() {
app.provide('baz', 2)
}
}
const PluginD: any = undefined
const Root: Component = {
setup() {
const foo = inject('foo')
const bar = inject('bar')
return document.createTextNode(`${foo},${bar}`)
},
}
const app = createVaporApp(Root)
app.use(PluginA)
app.use(PluginB, 1, 1)
app.use(PluginC)
const root = document.createElement('div')
app.mount(root)
expect(root.innerHTML).toBe(`1,2`)
app.use(PluginA)
expect(
`Plugin has already been applied to target app`,
).toHaveBeenWarnedTimes(1)
app.use(PluginD)
expect(
`A plugin must either be a function or an object with an "install" ` +
`function.`,
).toHaveBeenWarnedTimes(1)
})
})

View File

@ -21,6 +21,8 @@ export function createVaporApp(
}
const context = createAppContext()
const installedPlugins = new WeakSet()
let instance: ComponentInternalInstance
const app: App = {
@ -40,6 +42,24 @@ export function createVaporApp(
}
},
use(plugin: Plugin, ...options: any[]) {
if (installedPlugins.has(plugin)) {
__DEV__ && warn(`Plugin has already been applied to target app.`)
} else if (plugin && isFunction(plugin.install)) {
installedPlugins.add(plugin)
plugin.install(app, ...options)
} else if (isFunction(plugin)) {
installedPlugins.add(plugin)
plugin(app, ...options)
} else if (__DEV__) {
warn(
`A plugin must either be a function or an object with an "install" ` +
`function.`,
)
}
return app
},
mount(rootContainer): any {
if (!instance) {
instance = createComponentInstance(
@ -107,10 +127,30 @@ export function createAppContext(): AppContext {
}
}
type PluginInstallFunction<Options = any[]> = Options extends unknown[]
? (app: App, ...options: Options) => any
: (app: App, options: Options) => any
export type ObjectPlugin<Options = any[]> = {
install: PluginInstallFunction<Options>
}
export type FunctionPlugin<Options = any[]> = PluginInstallFunction<Options> &
Partial<ObjectPlugin<Options>>
export type Plugin<Options = any[]> =
| FunctionPlugin<Options>
| ObjectPlugin<Options>
export interface App {
version: string
config: AppConfig
use<Options extends unknown[]>(
plugin: Plugin<Options>,
...options: Options
): this
use<Options>(plugin: Plugin<Options>, options: Options): this
mount(
rootContainer: ParentNode | string,
isHydrate?: boolean,

View File

@ -121,6 +121,9 @@ export {
type App,
type AppConfig,
type AppContext,
type Plugin,
type ObjectPlugin,
type FunctionPlugin,
} from './apiCreateVaporApp'
export { createIf } from './apiCreateIf'
export { createFor } from './apiCreateFor'