feat: provide ability to overwrite feature flags in esm-bundler builds

e.g. by replacing `__VUE_OPTIONS_API__` to `false` using webpack's
`DefinePlugin`, the final bundle will drop all code supporting the
options API.

This does not break existing usage, but requires the user to explicitly
configure the feature flags via bundlers to properly tree-shake the
disabled branches. As a result, users will see a console warning if
the flags have not been properly configured.
This commit is contained in:
Evan You
2020-07-20 21:51:30 -04:00
parent dabdc5e115
commit 54727f9874
15 changed files with 123 additions and 45 deletions

View File

@@ -13,7 +13,7 @@ import { isFunction, NO, isObject } from '@vue/shared'
import { warn } from './warning'
import { createVNode, cloneVNode, VNode } from './vnode'
import { RootHydrateFunction } from './hydration'
import { initApp, appUnmounted } from './devtools'
import { devtoolsInitApp, devtoolsUnmountApp } from './devtools'
import { version } from '.'
export interface App<HostElement = any> {
@@ -32,7 +32,7 @@ export interface App<HostElement = any> {
unmount(rootContainer: HostElement | string): void
provide<T>(key: InjectionKey<T> | string, value: T): this
// internal. We need to expose these for the server-renderer and devtools
// internal, but we need to expose these for the server-renderer and devtools
_component: Component
_props: Data | null
_container: HostElement | null
@@ -50,7 +50,6 @@ export interface AppConfig {
// @private
readonly isNativeTag?: (tag: string) => boolean
devtools: boolean
performance: boolean
optionMergeStrategies: Record<string, OptionMergeFunction>
globalProperties: Record<string, any>
@@ -68,15 +67,13 @@ export interface AppConfig {
}
export interface AppContext {
app: App // for devtools
config: AppConfig
mixins: ComponentOptions[]
components: Record<string, PublicAPIComponent>
directives: Record<string, Directive>
provides: Record<string | symbol, any>
reload?: () => void // HMR only
// internal for devtools
__app?: App
}
type PluginInstallFunction = (app: App, ...options: any[]) => any
@@ -89,9 +86,9 @@ export type Plugin =
export function createAppContext(): AppContext {
return {
app: null as any,
config: {
isNativeTag: NO,
devtools: true,
performance: false,
globalProperties: {},
optionMergeStrategies: {},
@@ -126,7 +123,7 @@ export function createAppAPI<HostElement>(
let isMounted = false
const app: App = {
const app: App = (context.app = {
_component: rootComponent as Component,
_props: rootProps,
_container: null,
@@ -165,7 +162,7 @@ export function createAppAPI<HostElement>(
},
mixin(mixin: ComponentOptions) {
if (__FEATURE_OPTIONS__) {
if (__FEATURE_OPTIONS_API__) {
if (!context.mixins.includes(mixin)) {
context.mixins.push(mixin)
} else if (__DEV__) {
@@ -230,8 +227,12 @@ export function createAppAPI<HostElement>(
}
isMounted = true
app._container = rootContainer
// for devtools and telemetry
;(rootContainer as any).__vue_app__ = app
__DEV__ && initApp(app, version)
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
devtoolsInitApp(app, version)
}
return vnode.component!.proxy
} else if (__DEV__) {
@@ -247,8 +248,7 @@ export function createAppAPI<HostElement>(
unmount() {
if (isMounted) {
render(null, app._container)
__DEV__ && appUnmounted(app)
devtoolsUnmountApp(app)
} else if (__DEV__) {
warn(`Cannot unmount an app that is not mounted.`)
}
@@ -267,9 +267,7 @@ export function createAppAPI<HostElement>(
return app
}
}
context.__app = app
})
return app
}