| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // This entry is the "full-build" that includes both the runtime
- // and the compiler, and supports on-the-fly compilation of the template option.
- import { initDev } from './dev'
- import {
- type CompilerError,
- type CompilerOptions,
- compile,
- } from '@vue/compiler-dom'
- import {
- type RenderFunction,
- registerRuntimeCompiler,
- warn,
- } from '@vue/runtime-dom'
- import * as runtimeDom from '@vue/runtime-dom'
- import {
- EMPTY_OBJ,
- NOOP,
- extend,
- generateCodeFrame,
- isString,
- } from '@vue/shared'
- import type { InternalRenderFunction } from 'packages/runtime-core/src/component'
- if (__DEV__) {
- initDev()
- }
- const compileCache = new WeakMap<
- CompilerOptions,
- Record<string, RenderFunction>
- >()
- function getCache(options?: CompilerOptions) {
- let c = compileCache.get(options ?? EMPTY_OBJ)
- if (!c) {
- c = Object.create(null) as Record<string, RenderFunction>
- compileCache.set(options ?? EMPTY_OBJ, c)
- }
- return c
- }
- function compileToFunction(
- template: string | HTMLElement,
- options?: CompilerOptions,
- ): RenderFunction {
- if (!isString(template)) {
- if (template.nodeType) {
- template = template.innerHTML
- } else {
- __DEV__ && warn(`invalid template option: `, template)
- return NOOP
- }
- }
- const key = template
- const cache = getCache(options)
- const cached = cache[key]
- if (cached) {
- return cached
- }
- if (template[0] === '#') {
- const el = document.querySelector(template)
- if (__DEV__ && !el) {
- warn(`Template element not found or is empty: ${template}`)
- }
- // __UNSAFE__
- // Reason: potential execution of JS expressions in in-DOM template.
- // The user must make sure the in-DOM template is trusted. If it's rendered
- // by the server, the template should not contain any user data.
- template = el ? el.innerHTML : ``
- }
- const opts = extend(
- {
- hoistStatic: true,
- onError: __DEV__ ? onError : undefined,
- onWarn: __DEV__ ? e => onError(e, true) : NOOP,
- } as CompilerOptions,
- options,
- )
- if (!opts.isCustomElement && typeof customElements !== 'undefined') {
- opts.isCustomElement = tag => !!customElements.get(tag)
- }
- const { code } = compile(template, opts)
- function onError(err: CompilerError, asWarning = false) {
- const message = asWarning
- ? err.message
- : `Template compilation error: ${err.message}`
- const codeFrame =
- err.loc &&
- generateCodeFrame(
- template as string,
- err.loc.start.offset,
- err.loc.end.offset,
- )
- warn(codeFrame ? `${message}\n${codeFrame}` : message)
- }
- // The wildcard import results in a huge object with every export
- // with keys that cannot be mangled, and can be quite heavy size-wise.
- // In the global build we know `Vue` is available globally so we can avoid
- // the wildcard object.
- const render = (
- __GLOBAL__ ? new Function(code)() : new Function('Vue', code)(runtimeDom)
- ) as RenderFunction
- // mark the function as runtime compiled
- ;(render as InternalRenderFunction)._rc = true
- return (cache[key] = render)
- }
- registerRuntimeCompiler(compileToFunction)
- export { compileToFunction as compile }
- export * from '@vue/runtime-dom'
|