compile.ts 3.7 KB

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