Skip to content

Commit 24850a9

Browse files
committed
wip: initial compat build setup
1 parent 870f2a7 commit 24850a9

14 files changed

+431
-18
lines changed

.eslintrc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ module.exports = {
4141
},
4242
// Packages targeting DOM
4343
{
44-
files: ['packages/{vue,runtime-dom}/**'],
44+
files: ['packages/{vue,vue-compat,runtime-dom}/**'],
4545
rules: {
4646
'no-restricted-globals': ['error', ...NodeGlobals]
4747
}

packages/global.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ declare var __ESM_BROWSER__: boolean
88
declare var __NODE_JS__: boolean
99
declare var __COMMIT__: string
1010
declare var __VERSION__: string
11+
declare var __COMPAT__: boolean
1112

1213
// Feature flags
1314
declare var __FEATURE_OPTIONS_API__: boolean

packages/runtime-dom/src/index.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ import {
1313
import { nodeOps } from './nodeOps'
1414
import { patchProp, forcePatchProp } from './patchProp'
1515
// Importing from the compiler, will be tree-shaken in prod
16-
import { isFunction, isString, isHTMLTag, isSVGTag, extend } from '@vue/shared'
16+
import {
17+
isFunction,
18+
isString,
19+
isHTMLTag,
20+
isSVGTag,
21+
extend,
22+
warnDeprecation,
23+
DeprecationTypes
24+
} from '@vue/shared'
1725

1826
declare module '@vue/reactivity' {
1927
export interface RefUnwrapBailTypes {
@@ -63,8 +71,24 @@ export const createApp = ((...args) => {
6371
app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {
6472
const container = normalizeContainer(containerOrSelector)
6573
if (!container) return
74+
75+
// 2.x compat check
76+
if (__COMPAT__ && __DEV__) {
77+
for (let i = 0; i < container.attributes.length; i++) {
78+
const attr = container.attributes[i]
79+
if (attr.name !== 'v-cloak' && /^(v-|:|@)/.test(attr.name)) {
80+
warnDeprecation(DeprecationTypes.DOM_TEMPLATE_MOUNT)
81+
break
82+
}
83+
}
84+
}
85+
6686
const component = app._component
6787
if (!isFunction(component) && !component.render && !component.template) {
88+
// __UNSAFE__
89+
// Reason: potential execution of JS expressions in in-DOM template.
90+
// The user must make sure the in-DOM template is trusted. If it's
91+
// rendered by the server, the template should not contain any user data.
6892
component.template = container.innerHTML
6993
}
7094
// clear content before mounting

packages/shared/src/deprecations.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export const enum DeprecationTypes {
2+
DOM_TEMPLATE_MOUNT
3+
}
4+
5+
type DeprecationData = {
6+
message: string
7+
link?: string
8+
}
9+
10+
const deprecations: Record<DeprecationTypes, DeprecationData> = {
11+
[DeprecationTypes.DOM_TEMPLATE_MOUNT]: {
12+
message:
13+
`Vue detected directives on the mount container. ` +
14+
`In Vue 3, the container is no longer considered part of the template ` +
15+
`and will not be processed/replaced.`,
16+
link: `https://v3.vuejs.org/guide/migration/mount-changes.html`
17+
}
18+
}
19+
20+
export function warnDeprecation(key: DeprecationTypes) {
21+
const { message, link } = deprecations[key]
22+
console.warn(
23+
`[Deprecation]: ${message}${link ? `\nFor more details, see ${link}` : ``}`
24+
)
25+
}

packages/shared/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export * from './domAttrConfig'
1212
export * from './escapeHtml'
1313
export * from './looseEqual'
1414
export * from './toDisplayString'
15+
export * from './deprecations'
1516

1617
/**
1718
* List of @babel/parser plugins that are used for template expression

packages/vue-compat/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# @vue/compat
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "../../api-extractor.json",
3+
"mainEntryPointFilePath": "./dist/packages/<unscopedPackageName>/src/index.d.ts",
4+
"dtsRollup": {
5+
"publicTrimmedFilePath": "./dist/<unscopedPackageName>.d.ts"
6+
}
7+
}

packages/vue-compat/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict'
2+
3+
if (process.env.NODE_ENV === 'production') {
4+
module.exports = require('./dist/compat.cjs.prod.js')
5+
} else {
6+
module.exports = require('./dist/compat.cjs.js')
7+
}

packages/vue-compat/package.json

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@vue/compat",
3+
"version": "3.0.11",
4+
"description": "@vue/compat",
5+
"main": "index.js",
6+
"module": "dist/vue.esm-bundler.js",
7+
"types": "dist/vue.d.ts",
8+
"unpkg": "dist/vue.global.js",
9+
"jsdelivr": "dist/vue.global.js",
10+
"files": [
11+
"index.js",
12+
"dist"
13+
],
14+
"buildOptions": {
15+
"name": "Vue",
16+
"filename": "vue",
17+
"compat": true,
18+
"formats": [
19+
"esm-bundler",
20+
"esm-bundler-runtime",
21+
"cjs",
22+
"global",
23+
"global-runtime",
24+
"esm-browser",
25+
"esm-browser-runtime"
26+
]
27+
},
28+
"repository": {
29+
"type": "git",
30+
"url": "git+https://github.com/vuejs/vue.git"
31+
},
32+
"keywords": [
33+
"vue"
34+
],
35+
"author": "Evan You",
36+
"license": "MIT",
37+
"bugs": {
38+
"url": "https://github.com/vuejs/vue/issues"
39+
},
40+
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/vue-compat#readme",
41+
"peerDependencies": {
42+
"vue": "3.0.11"
43+
}
44+
}

packages/vue-compat/src/apiGlobal.ts

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { reactive } from '@vue/reactivity'
2+
import {
3+
createApp,
4+
defineComponent,
5+
nextTick,
6+
App,
7+
AppConfig,
8+
Plugin,
9+
Component,
10+
ComponentOptions,
11+
ComponentPublicInstance,
12+
Directive,
13+
RenderFunction,
14+
isRuntimeOnly
15+
} from '@vue/runtime-dom'
16+
17+
// TODO make these getter/setters and trigger deprecation warnings
18+
export type LegacyConfig = AppConfig & {
19+
/**
20+
* @deprecated `config.silent` option has been removed
21+
*/
22+
silent?: boolean
23+
/**
24+
* @deprecated use __VUE_PROD_DEVTOOLS__ compile-time feature flag instead
25+
* https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags
26+
*/
27+
devtools?: boolean
28+
/**
29+
* @deprecated use `config.isCustomElement` instead
30+
* https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement
31+
*/
32+
ignoredElements?: (string | RegExp)[]
33+
/**
34+
* @deprecated
35+
* https://v3.vuejs.org/guide/migration/keycode-modifiers.html
36+
*/
37+
keyCodes?: Record<string, number | number[]>
38+
/**
39+
* @deprecated
40+
* https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed
41+
*/
42+
productionTip?: boolean
43+
}
44+
45+
/**
46+
* @deprecated the default `Vue` export has been removed in Vue 3. The type for
47+
* the default export is provided only for migration purposes. Please use
48+
* named imports instead - e.g. `import { createApp } from 'vue'`.
49+
*/
50+
export type GlobalVue = Pick<App, 'version' | 'component' | 'directive'> & {
51+
// no inference here since these types are not meant for actual use - they
52+
// are merely here to provide type checks for internal implementation and
53+
// information for migration.
54+
new (options?: ComponentOptions): ComponentPublicInstance
55+
56+
version: string
57+
config: LegacyConfig
58+
59+
extend: typeof defineComponent
60+
nextTick: typeof nextTick
61+
62+
use(plugin: Plugin, ...options: any[]): GlobalVue
63+
mixin(mixin: ComponentOptions): GlobalVue
64+
65+
component(name: string): Component | undefined
66+
component(name: string, component: Component): GlobalVue
67+
directive(name: string): Directive | undefined
68+
directive(name: string, directive: Directive): GlobalVue
69+
70+
compile(template: string): RenderFunction
71+
72+
/**
73+
* @deprecated Vue 3 no longer needs set() for adding new properties.
74+
*/
75+
set(target: any, key: string | number | symbol, value: any): void
76+
/**
77+
* @deprecated Vue 3 no longer needs delete() for property deletions.
78+
*/
79+
delete(target: any, key: string | number | symbol): void
80+
/**
81+
* @deprecated use `reactive` instead.
82+
*/
83+
observable: typeof reactive
84+
/**
85+
* @deprecated filters have been removed from Vue 3.
86+
*/
87+
filter(name: string, arg: any): null
88+
}
89+
90+
export const Vue: GlobalVue = function Vue(options: ComponentOptions = {}) {
91+
const app = createApp(options)
92+
// copy over global config mutations
93+
for (const key in singletonApp.config) {
94+
if (
95+
key !== 'isNativeTag' &&
96+
!(key === 'isCustomElement' && isRuntimeOnly())
97+
) {
98+
// @ts-ignore
99+
app.config[key] = singletonApp.config[key]
100+
}
101+
}
102+
if (options.el) {
103+
return app.mount(options.el)
104+
}
105+
} as any
106+
107+
const singletonApp = createApp({})
108+
109+
Vue.version = __VERSION__
110+
Vue.config = singletonApp.config
111+
112+
Vue.extend = defineComponent
113+
Vue.nextTick = nextTick
114+
115+
Vue.set = (target, key, value) => {
116+
// TODO deprecation warnings
117+
target[key] = value
118+
}
119+
Vue.delete = (target, key) => {
120+
// TODO deprecation warnings
121+
delete target[key]
122+
}
123+
// TODO wrap with deprecation warning
124+
Vue.observable = reactive
125+
126+
Vue.use = (p, ...options) => {
127+
singletonApp.use(p, ...options)
128+
return Vue
129+
}
130+
131+
Vue.mixin = m => {
132+
singletonApp.mixin(m)
133+
return Vue
134+
}
135+
136+
Vue.component = ((name: string, comp: any) => {
137+
if (comp) {
138+
singletonApp.component(name, comp)
139+
return Vue
140+
} else {
141+
return singletonApp.component(name)
142+
}
143+
}) as any
144+
145+
Vue.directive = ((name: string, dir: any) => {
146+
if (dir) {
147+
singletonApp.directive(name, dir)
148+
return Vue
149+
} else {
150+
return singletonApp.directive(name)
151+
}
152+
}) as any
153+
154+
Vue.filter = ((name: string, filter: any) => {
155+
// TODO deprecation warning
156+
// TODO compiler warning for filters (maybe behavior compat?)
157+
}) as any

packages/vue-compat/src/dev.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { initCustomFormatter } from '@vue/runtime-dom'
2+
3+
export function initDev() {
4+
if (__BROWSER__) {
5+
if (!__ESM_BUNDLER__) {
6+
console.info(
7+
`You are running a development build of Vue.\n` +
8+
`Make sure to use the production build (*.prod.js) when deploying for production.`
9+
)
10+
}
11+
12+
initCustomFormatter()
13+
}
14+
}

0 commit comments

Comments
 (0)