vue3-core/packages/vue/src/index.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

121 lines
3.1 KiB
TypeScript
Raw Normal View History

// 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'
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()
}
2020-07-17 06:18:52 +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
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)
2021-04-18 04:05:27 +08:00
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.
2021-07-20 06:24:18 +08:00
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)
2019-09-20 12:12:37 +08:00
}
registerRuntimeCompiler(compileToFunction)
2019-09-20 12:24:16 +08:00
export { compileToFunction as compile }
2018-10-27 03:44:50 +08:00
export * from '@vue/runtime-dom'