compile.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { CompilerOptions } from './options'
  2. import { baseParse } from './parse'
  3. import { transform, NodeTransform, DirectiveTransform } from './transform'
  4. import { generate, CodegenResult } from './codegen'
  5. import { RootNode } from './ast'
  6. import { isString } from '@vue/shared'
  7. import { transformIf } from './transforms/vIf'
  8. import { transformFor } from './transforms/vFor'
  9. import { transformExpression } from './transforms/transformExpression'
  10. import { transformSlotOutlet } from './transforms/transformSlotOutlet'
  11. import { transformElement } from './transforms/transformElement'
  12. import { transformOn } from './transforms/vOn'
  13. import { transformBind } from './transforms/vBind'
  14. import { trackSlotScopes, trackVForSlotScopes } from './transforms/vSlot'
  15. import { transformText } from './transforms/transformText'
  16. import { transformOnce } from './transforms/vOnce'
  17. import { transformModel } from './transforms/vModel'
  18. import { defaultOnError, createCompilerError, ErrorCodes } from './errors'
  19. export type TransformPreset = [
  20. NodeTransform[],
  21. Record<string, DirectiveTransform>
  22. ]
  23. export function getBaseTransformPreset(
  24. prefixIdentifiers?: boolean
  25. ): TransformPreset {
  26. return [
  27. [
  28. transformOnce,
  29. transformIf,
  30. transformFor,
  31. ...(!__BROWSER__ && prefixIdentifiers
  32. ? [
  33. // order is important
  34. trackVForSlotScopes,
  35. transformExpression
  36. ]
  37. : []),
  38. transformSlotOutlet,
  39. transformElement,
  40. trackSlotScopes,
  41. transformText
  42. ],
  43. {
  44. on: transformOn,
  45. bind: transformBind,
  46. model: transformModel
  47. }
  48. ]
  49. }
  50. // we name it `baseCompile` so that higher order compilers like
  51. // @vue/compiler-dom can export `compile` while re-exporting everything else.
  52. export function baseCompile(
  53. template: string | RootNode,
  54. options: CompilerOptions = {}
  55. ): CodegenResult {
  56. const onError = options.onError || defaultOnError
  57. const isModuleMode = options.mode === 'module'
  58. /* istanbul ignore if */
  59. if (__BROWSER__) {
  60. if (options.prefixIdentifiers === true) {
  61. onError(createCompilerError(ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED))
  62. } else if (isModuleMode) {
  63. onError(createCompilerError(ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED))
  64. }
  65. }
  66. const prefixIdentifiers =
  67. !__BROWSER__ && (options.prefixIdentifiers === true || isModuleMode)
  68. if (!prefixIdentifiers && options.cacheHandlers) {
  69. onError(createCompilerError(ErrorCodes.X_CACHE_HANDLER_NOT_SUPPORTED))
  70. }
  71. if (options.scopeId && !isModuleMode) {
  72. onError(createCompilerError(ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED))
  73. }
  74. const ast = isString(template) ? baseParse(template, options) : template
  75. const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(
  76. prefixIdentifiers
  77. )
  78. transform(ast, {
  79. ...options,
  80. prefixIdentifiers,
  81. nodeTransforms: [
  82. ...nodeTransforms,
  83. ...(options.nodeTransforms || []) // user transforms
  84. ],
  85. directiveTransforms: {
  86. ...directiveTransforms,
  87. ...(options.directiveTransforms || {}) // user transforms
  88. }
  89. })
  90. return generate(ast, {
  91. ...options,
  92. prefixIdentifiers
  93. })
  94. }