2019-12-18 07:24:01 +08:00
|
|
|
// This entry is the "full-build" that includes both the runtime
|
2019-09-20 12:24:16 +08:00
|
|
|
// and the compiler, and supports on-the-fly compilation of the template option.
|
2020-07-17 06:18:52 +08:00
|
|
|
import { initDev } from './dev'
|
2019-12-11 23:25:34 +08:00
|
|
|
import {
|
|
|
|
|
type CompilerError,
|
|
|
|
|
type CompilerOptions,
|
|
|
|
|
compile,
|
|
|
|
|
} from '@vue/compiler-dom'
|
2019-12-02 12:09:34 +08:00
|
|
|
import {
|
|
|
|
|
type RenderFunction,
|
|
|
|
|
registerRuntimeCompiler,
|
|
|
|
|
warn,
|
|
|
|
|
} from '@vue/runtime-dom'
|
2019-10-11 23:16:20 +08:00
|
|
|
import * as runtimeDom from '@vue/runtime-dom'
|
2023-12-04 16:43:30 +08:00
|
|
|
import {
|
|
|
|
|
EMPTY_OBJ,
|
|
|
|
|
NOOP,
|
|
|
|
|
extend,
|
|
|
|
|
generateCodeFrame,
|
2023-12-26 19:39:47 +08:00
|
|
|
isString,
|
2023-12-04 16:43:30 +08:00
|
|
|
} from '@vue/shared'
|
2020-07-28 23:11:26 +08:00
|
|
|
import type { InternalRenderFunction } from 'packages/runtime-core/src/component'
|
2019-12-02 12:09:34 +08:00
|
|
|
|
2021-02-25 04:59:38 +08:00
|
|
|
if (__DEV__) {
|
2021-01-06 01:54:43 +08:00
|
|
|
initDev()
|
|
|
|
|
}
|
2020-07-17 06:18:52 +08:00
|
|
|
|
2023-12-04 16:43:30 +08:00
|
|
|
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
|
|
|
|
|
}
|
2019-09-20 12:12:37 +08:00
|
|
|
|
2019-09-21 00:16:19 +08:00
|
|
|
function compileToFunction(
|
2019-12-02 12:09:34 +08:00
|
|
|
template: string | HTMLElement,
|
2019-09-21 00:16:19 +08:00
|
|
|
options?: CompilerOptions,
|
|
|
|
|
): RenderFunction {
|
2019-12-11 22:46:42 +08:00
|
|
|
if (!isString(template)) {
|
|
|
|
|
if (template.nodeType) {
|
|
|
|
|
template = template.innerHTML
|
|
|
|
|
} else {
|
|
|
|
|
__DEV__ && warn(`invalid template option: `, template)
|
|
|
|
|
return NOOP
|
2019-12-02 12:09:34 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-11 22:46:42 +08:00
|
|
|
const key = template
|
2023-12-04 16:43:30 +08:00
|
|
|
const cache = getCache(options)
|
|
|
|
|
const cached = cache[key]
|
2019-12-11 22:46:42 +08:00
|
|
|
if (cached) {
|
|
|
|
|
return cached
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (template[0] === '#') {
|
|
|
|
|
const el = document.querySelector(template)
|
|
|
|
|
if (__DEV__ && !el) {
|
|
|
|
|
warn(`Template element not found or is empty: ${template}`)
|
|
|
|
|
}
|
2020-02-13 04:00:32 +08:00
|
|
|
// __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.
|
2019-12-11 22:46:42 +08:00
|
|
|
template = el ? el.innerHTML : ``
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-30 11:30:52 +08:00
|
|
|
const opts = extend(
|
|
|
|
|
{
|
|
|
|
|
hoistStatic: true,
|
|
|
|
|
onError: __DEV__ ? onError : undefined,
|
|
|
|
|
onWarn: __DEV__ ? e => onError(e, true) : NOOP,
|
|
|
|
|
} as CompilerOptions,
|
|
|
|
|
options,
|
2020-06-11 04:54:23 +08:00
|
|
|
)
|
2019-10-11 23:16:20 +08:00
|
|
|
|
2022-08-30 11:30:52 +08:00
|
|
|
if (!opts.isCustomElement && typeof customElements !== 'undefined') {
|
|
|
|
|
opts.isCustomElement = tag => !!customElements.get(tag)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { code } = compile(template, opts)
|
|
|
|
|
|
2021-04-18 04:05:27 +08:00
|
|
|
function onError(err: CompilerError, asWarning = false) {
|
|
|
|
|
const message = asWarning
|
|
|
|
|
? err.message
|
|
|
|
|
: `Template compilation error: ${err.message}`
|
2021-04-16 23:51:47 +08:00
|
|
|
const codeFrame =
|
|
|
|
|
err.loc &&
|
|
|
|
|
generateCodeFrame(
|
|
|
|
|
template as string,
|
|
|
|
|
err.loc.start.offset,
|
|
|
|
|
err.loc.end.offset,
|
|
|
|
|
)
|
|
|
|
|
warn(codeFrame ? `${message}\n${codeFrame}` : message)
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-14 07:50:36 +08:00
|
|
|
// 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.
|
2021-07-20 06:24:18 +08:00
|
|
|
const render = (
|
|
|
|
|
__GLOBAL__ ? new Function(code)() : new Function('Vue', code)(runtimeDom)
|
|
|
|
|
) as RenderFunction
|
2020-07-28 23:11:26 +08:00
|
|
|
|
|
|
|
|
// mark the function as runtime compiled
|
|
|
|
|
;(render as InternalRenderFunction)._rc = true
|
|
|
|
|
|
2023-12-04 16:43:30 +08:00
|
|
|
return (cache[key] = render)
|
2019-09-20 12:12:37 +08:00
|
|
|
}
|
|
|
|
|
|
2019-09-21 00:16:19 +08:00
|
|
|
registerRuntimeCompiler(compileToFunction)
|
2019-09-20 12:24:16 +08:00
|
|
|
|
2019-09-21 00:16:19 +08:00
|
|
|
export { compileToFunction as compile }
|
2018-10-27 03:44:50 +08:00
|
|
|
export * from '@vue/runtime-dom'
|