index.ts 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. import {
  2. type App,
  3. type Component,
  4. type ConcreteComponent,
  5. type CreateAppFunction,
  6. type DefineComponent,
  7. DeprecationTypes,
  8. type Directive,
  9. type ElementNamespace,
  10. type HydrationRenderer,
  11. type Renderer,
  12. type RootHydrateFunction,
  13. type RootRenderFunction,
  14. compatUtils,
  15. createHydrationRenderer,
  16. createRenderer,
  17. isRuntimeOnly,
  18. warn,
  19. } from '@vue/runtime-core'
  20. import { nodeOps } from './nodeOps'
  21. import { patchProp } from './patchProp'
  22. export { nodeOps, patchProp }
  23. // Importing from the compiler, will be tree-shaken in prod
  24. import {
  25. NOOP,
  26. extend,
  27. isFunction,
  28. isHTMLTag,
  29. isMathMLTag,
  30. isSVGTag,
  31. isString,
  32. } from '@vue/shared'
  33. import type { TransitionProps } from './components/Transition'
  34. import type { TransitionGroupProps } from './components/TransitionGroup'
  35. import type { vShow } from './directives/vShow'
  36. import type { VOnDirective } from './directives/vOn'
  37. import type { VModelDirective } from './directives/vModel'
  38. /**
  39. * This is a stub implementation to prevent the need to use dom types.
  40. *
  41. * To enable proper types, add `"dom"` to `"lib"` in your `tsconfig.json`.
  42. */
  43. type DomType<T> = typeof globalThis extends { window: unknown } ? T : never
  44. declare module '@vue/reactivity' {
  45. export interface RefUnwrapBailTypes {
  46. runtimeDOMBailTypes: DomType<Node | Window>
  47. }
  48. }
  49. declare module '@vue/runtime-core' {
  50. interface GlobalComponents {
  51. Transition: DefineComponent<TransitionProps>
  52. TransitionGroup: DefineComponent<TransitionGroupProps>
  53. }
  54. interface GlobalDirectives {
  55. vShow: typeof vShow
  56. vOn: VOnDirective
  57. vBind: VModelDirective
  58. vIf: Directive<any, boolean>
  59. vOnce: Directive
  60. vSlot: Directive
  61. }
  62. }
  63. const rendererOptions = /*@__PURE__*/ extend({ patchProp }, nodeOps)
  64. // lazy create the renderer - this makes core renderer logic tree-shakable
  65. // in case the user only imports reactivity utilities from Vue.
  66. let renderer: Renderer<Element | ShadowRoot> | HydrationRenderer
  67. let enabledHydration = false
  68. function ensureRenderer(): Renderer<Element | ShadowRoot> {
  69. return (
  70. renderer ||
  71. (renderer = createRenderer<Node, Element | ShadowRoot>(rendererOptions))
  72. )
  73. }
  74. function ensureHydrationRenderer() {
  75. renderer = enabledHydration
  76. ? renderer
  77. : createHydrationRenderer(rendererOptions)
  78. enabledHydration = true
  79. return renderer as HydrationRenderer
  80. }
  81. // use explicit type casts here to avoid import() calls in rolled-up d.ts
  82. export const render = ((...args) => {
  83. ensureRenderer().render(...args)
  84. }) as RootRenderFunction<Element | ShadowRoot>
  85. export const hydrate = ((...args) => {
  86. ensureHydrationRenderer().hydrate(...args)
  87. }) as RootHydrateFunction
  88. export const createApp = ((...args) => {
  89. const app = ensureRenderer().createApp(...args)
  90. if (__DEV__) {
  91. injectNativeTagCheck(app)
  92. injectCompilerOptionsCheck(app)
  93. }
  94. const { mount } = app
  95. app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {
  96. const container = normalizeContainer(containerOrSelector)
  97. if (!container) return
  98. const component = app._component as ConcreteComponent
  99. if (!isFunction(component) && !component.render && !component.template) {
  100. // __UNSAFE__
  101. // Reason: potential execution of JS expressions in in-DOM template.
  102. // The user must make sure the in-DOM template is trusted. If it's
  103. // rendered by the server, the template should not contain any user data.
  104. component.template = container.innerHTML
  105. // 2.x compat check
  106. if (__COMPAT__ && __DEV__ && container.nodeType === 1) {
  107. for (let i = 0; i < (container as Element).attributes.length; i++) {
  108. const attr = (container as Element).attributes[i]
  109. if (attr.name !== 'v-cloak' && /^(?:v-|:|@)/.test(attr.name)) {
  110. compatUtils.warnDeprecation(
  111. DeprecationTypes.GLOBAL_MOUNT_CONTAINER,
  112. null,
  113. )
  114. break
  115. }
  116. }
  117. }
  118. }
  119. // clear content before mounting
  120. if (container.nodeType === 1) {
  121. container.textContent = ''
  122. }
  123. const proxy = mount(container, false, resolveRootNamespace(container))
  124. if (container instanceof Element) {
  125. container.removeAttribute('v-cloak')
  126. container.setAttribute('data-v-app', '')
  127. }
  128. return proxy
  129. }
  130. return app
  131. }) as CreateAppFunction<Element, Component>
  132. export const createSSRApp = ((...args) => {
  133. const app = ensureHydrationRenderer().createApp(...args)
  134. if (__DEV__) {
  135. injectNativeTagCheck(app)
  136. injectCompilerOptionsCheck(app)
  137. }
  138. const { mount } = app
  139. app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {
  140. const container = normalizeContainer(containerOrSelector)
  141. if (container) {
  142. return mount(container, true, resolveRootNamespace(container))
  143. }
  144. }
  145. return app
  146. }) as CreateAppFunction<Element>
  147. function resolveRootNamespace(
  148. container: Element | ShadowRoot,
  149. ): ElementNamespace {
  150. if (container instanceof SVGElement) {
  151. return 'svg'
  152. }
  153. if (
  154. typeof MathMLElement === 'function' &&
  155. container instanceof MathMLElement
  156. ) {
  157. return 'mathml'
  158. }
  159. }
  160. function injectNativeTagCheck(app: App) {
  161. // Inject `isNativeTag`
  162. // this is used for component name validation (dev only)
  163. Object.defineProperty(app.config, 'isNativeTag', {
  164. value: (tag: string) => isHTMLTag(tag) || isSVGTag(tag) || isMathMLTag(tag),
  165. writable: false,
  166. })
  167. }
  168. // dev only
  169. function injectCompilerOptionsCheck(app: App) {
  170. if (isRuntimeOnly()) {
  171. const isCustomElement = app.config.isCustomElement
  172. Object.defineProperty(app.config, 'isCustomElement', {
  173. get() {
  174. return isCustomElement
  175. },
  176. set() {
  177. warn(
  178. `The \`isCustomElement\` config option is deprecated. Use ` +
  179. `\`compilerOptions.isCustomElement\` instead.`,
  180. )
  181. },
  182. })
  183. const compilerOptions = app.config.compilerOptions
  184. const msg =
  185. `The \`compilerOptions\` config option is only respected when using ` +
  186. `a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
  187. `Since you are using the runtime-only build, \`compilerOptions\` ` +
  188. `must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
  189. `- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
  190. `- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
  191. `- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-sfc`
  192. Object.defineProperty(app.config, 'compilerOptions', {
  193. get() {
  194. warn(msg)
  195. return compilerOptions
  196. },
  197. set() {
  198. warn(msg)
  199. },
  200. })
  201. }
  202. }
  203. /**
  204. * @internal
  205. */
  206. function normalizeContainer<T extends ParentNode>(
  207. container: T | string,
  208. ): T | null {
  209. if (isString(container)) {
  210. const res = document.querySelector(container)
  211. if (__DEV__ && !res) {
  212. warn(
  213. `Failed to mount app: mount target selector "${container}" returned null.`,
  214. )
  215. }
  216. return res as any
  217. }
  218. if (
  219. __DEV__ &&
  220. window.ShadowRoot &&
  221. container instanceof window.ShadowRoot &&
  222. container.mode === 'closed'
  223. ) {
  224. warn(
  225. `mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`,
  226. )
  227. }
  228. return container as any
  229. }
  230. // Custom element support
  231. export {
  232. defineCustomElement,
  233. defineSSRCustomElement,
  234. useShadowRoot,
  235. useHost,
  236. VueElement,
  237. VueElementBase,
  238. type VueElementConstructor,
  239. type CustomElementOptions,
  240. } from './apiCustomElement'
  241. // SFC CSS utilities
  242. export { useCssModule } from './helpers/useCssModule'
  243. export { useCssVars } from './helpers/useCssVars'
  244. // DOM-only components
  245. export { Transition, type TransitionProps } from './components/Transition'
  246. export {
  247. TransitionGroup,
  248. type TransitionGroupProps,
  249. } from './components/TransitionGroup'
  250. // **Internal** DOM-only runtime directive helpers
  251. export {
  252. vModelText,
  253. vModelCheckbox,
  254. vModelRadio,
  255. vModelSelect,
  256. vModelDynamic,
  257. } from './directives/vModel'
  258. export { withModifiers, withKeys } from './directives/vOn'
  259. export { vShow } from './directives/vShow'
  260. import { initVModelForSSR } from './directives/vModel'
  261. import { initVShowForSSR } from './directives/vShow'
  262. let ssrDirectiveInitialized = false
  263. /**
  264. * @internal
  265. */
  266. export const initDirectivesForSSR: () => void = __SSR__
  267. ? () => {
  268. if (!ssrDirectiveInitialized) {
  269. ssrDirectiveInitialized = true
  270. initVModelForSSR()
  271. initVShowForSSR()
  272. }
  273. }
  274. : NOOP
  275. // re-export everything from core
  276. // h, Component, reactivity API, nextTick, flags & types
  277. export * from '@vue/runtime-core'
  278. export * from './jsx'
  279. // VAPOR -----------------------------------------------------------------------
  280. // Everything below are exposed for vapor only and can change any time.
  281. // They are also trimmed from non-bundler builds.
  282. /**
  283. * @internal
  284. */
  285. export { ensureRenderer, ensureHydrationRenderer, normalizeContainer }
  286. /**
  287. * @internal
  288. */
  289. export { patchStyle } from './modules/style'
  290. /**
  291. * @internal
  292. */
  293. export { shouldSetAsProp } from './patchProp'
  294. /**
  295. * @internal
  296. */
  297. export { baseUseCssVars, setVarsOnNode } from './helpers/useCssVars'
  298. /**
  299. * @internal
  300. */
  301. export {
  302. vShowOriginalDisplay,
  303. vShowHidden,
  304. type VShowElement,
  305. } from './directives/vShow'
  306. /**
  307. * @internal
  308. */
  309. export {
  310. vModelTextInit,
  311. vModelTextUpdate,
  312. vModelCheckboxInit,
  313. vModelCheckboxUpdate,
  314. getValue as vModelGetValue,
  315. vModelSelectInit,
  316. vModelSetSelected,
  317. } from './directives/vModel'
  318. /**
  319. * @internal
  320. */
  321. export { svgNS } from './nodeOps'
  322. /**
  323. * @internal
  324. */
  325. export { xlinkNS } from './modules/attrs'
  326. /**
  327. * @internal
  328. */
  329. export {
  330. resolveTransitionProps,
  331. TransitionPropsValidators,
  332. forceReflow,
  333. type ElementWithTransition,
  334. } from './components/Transition'
  335. /**
  336. * @internal
  337. */
  338. export {
  339. hasCSSTransform,
  340. callPendingCbs,
  341. handleMovedChildren,
  342. baseApplyTranslation,
  343. } from './components/TransitionGroup'
  344. /**
  345. * @internal
  346. */
  347. export { unsafeToTrustedHTML } from './nodeOps'