index.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // This entry is the "full-build" that includes both the runtime
  2. // and the compiler, and supports on-the-fly compilation of the template option.
  3. import { compile, CompilerOptions, CompilerError } from '@vue/compiler-dom'
  4. import { registerRuntimeCompiler, RenderFunction, warn } from '@vue/runtime-dom'
  5. import * as runtimeDom from '@vue/runtime-dom'
  6. import { isString, NOOP, generateCodeFrame } from '@vue/shared'
  7. const compileCache: Record<string, RenderFunction> = Object.create(null)
  8. function compileToFunction(
  9. template: string | HTMLElement,
  10. options?: CompilerOptions
  11. ): RenderFunction {
  12. if (!isString(template)) {
  13. if (template.nodeType) {
  14. template = template.innerHTML
  15. } else {
  16. __DEV__ && warn(`invalid template option: `, template)
  17. return NOOP
  18. }
  19. }
  20. const key = template
  21. const cached = compileCache[key]
  22. if (cached) {
  23. return cached
  24. }
  25. if (template[0] === '#') {
  26. const el = document.querySelector(template)
  27. if (__DEV__ && !el) {
  28. warn(`Template element not found or is empty: ${template}`)
  29. }
  30. // __UNSAFE__
  31. // Reason: potential execution of JS expressions in in-DOM template.
  32. // The user must make sure the in-DOM template is trusted. If it's rendered
  33. // by the server, the template should not contain any user data.
  34. template = el ? el.innerHTML : ``
  35. }
  36. const { code } = compile(template, {
  37. hoistStatic: true,
  38. onError(err: CompilerError) {
  39. if (__DEV__) {
  40. const message = `Template compilation error: ${err.message}`
  41. const codeFrame =
  42. err.loc &&
  43. generateCodeFrame(
  44. template as string,
  45. err.loc.start.offset,
  46. err.loc.end.offset
  47. )
  48. warn(codeFrame ? `${message}\n${codeFrame}` : message)
  49. } else {
  50. throw err
  51. }
  52. },
  53. ...options
  54. })
  55. // The wildcard import results in a huge object with every export
  56. // with keys that cannot be mangled, and can be quite heavy size-wise.
  57. // In the global build we know `Vue` is available globally so we can avoid
  58. // the wildcard object.
  59. const render = (__GLOBAL__
  60. ? new Function(code)()
  61. : new Function('Vue', code)(runtimeDom)) as RenderFunction
  62. return (compileCache[key] = render)
  63. }
  64. registerRuntimeCompiler(compileToFunction)
  65. export { compileToFunction as compile }
  66. export * from '@vue/runtime-dom'
  67. import './devCheck'