packages/compiler-sfc/src/compileTemplate.ts TYPESCRIPT 206 lines View on github.com → Search inside
1import { BindingMetadata, TemplateCompiler } from './types'2import assetUrlsModule, {3  AssetURLOptions,4  TransformAssetUrlsOptions5} from './templateCompilerModules/assetUrl'6import srcsetModule from './templateCompilerModules/srcset'7import consolidate from '@vue/consolidate'8import * as _compiler from 'web/entry-compiler'9import { prefixIdentifiers } from './prefixIdentifiers'10import { CompilerOptions, WarningMessage } from 'types/compiler'1112export interface SFCTemplateCompileOptions {13  source: string14  filename: string15  compiler?: TemplateCompiler16  compilerOptions?: CompilerOptions17  transformAssetUrls?: AssetURLOptions | boolean18  transformAssetUrlsOptions?: TransformAssetUrlsOptions19  preprocessLang?: string20  preprocessOptions?: any21  transpileOptions?: any22  isProduction?: boolean23  isFunctional?: boolean24  optimizeSSR?: boolean25  prettify?: boolean26  isTS?: boolean27  bindings?: BindingMetadata28}2930export interface SFCTemplateCompileResults {31  ast: Object | undefined32  code: string33  source: string34  tips: (string | WarningMessage)[]35  errors: (string | WarningMessage)[]36}3738export function compileTemplate(39  options: SFCTemplateCompileOptions40): SFCTemplateCompileResults {41  const { preprocessLang } = options42  const preprocessor = preprocessLang && consolidate[preprocessLang]43  if (preprocessor) {44    return actuallyCompile(45      Object.assign({}, options, {46        source: preprocess(options, preprocessor)47      })48    )49  } else if (preprocessLang) {50    return {51      ast: {},52      code: `var render = function () {}\n` + `var staticRenderFns = []\n`,53      source: options.source,54      tips: [55        `Component ${options.filename} uses lang ${preprocessLang} for template. Please install the language preprocessor.`56      ],57      errors: [58        `Component ${options.filename} uses lang ${preprocessLang} for template, however it is not installed.`59      ]60    }61  } else {62    return actuallyCompile(options)63  }64}6566function preprocess(67  options: SFCTemplateCompileOptions,68  preprocessor: any69): string {70  const { source, filename, preprocessOptions } = options7172  const finalPreprocessOptions = Object.assign(73    {74      filename75    },76    preprocessOptions77  )7879  // Consolidate exposes a callback based API, but the callback is in fact80  // called synchronously for most templating engines. In our case, we have to81  // expose a synchronous API so that it is usable in Jest transforms (which82  // have to be sync because they are applied via Node.js require hooks)83  let res: any, err84  preprocessor.render(85    source,86    finalPreprocessOptions,87    (_err: Error | null, _res: string) => {88      if (_err) err = _err89      res = _res90    }91  )9293  if (err) throw err94  return res95}9697function actuallyCompile(98  options: SFCTemplateCompileOptions99): SFCTemplateCompileResults {100  const {101    source,102    compiler = _compiler,103    compilerOptions = {},104    transpileOptions = {},105    transformAssetUrls,106    transformAssetUrlsOptions,107    isProduction = process.env.NODE_ENV === 'production',108    isFunctional = false,109    optimizeSSR = false,110    prettify = true,111    isTS = false,112    bindings113  } = options114115  const compile =116    optimizeSSR && compiler.ssrCompile ? compiler.ssrCompile : compiler.compile117118  let finalCompilerOptions = compilerOptions119  if (transformAssetUrls) {120    const builtInModules = [121      transformAssetUrls === true122        ? assetUrlsModule(undefined, transformAssetUrlsOptions)123        : assetUrlsModule(transformAssetUrls, transformAssetUrlsOptions),124      srcsetModule(transformAssetUrlsOptions)125    ]126    finalCompilerOptions = Object.assign({}, compilerOptions, {127      modules: [...builtInModules, ...(compilerOptions.modules || [])],128      filename: options.filename129    })130  }131  finalCompilerOptions.bindings = bindings132133  const { ast, render, staticRenderFns, tips, errors } = compile(134    source,135    finalCompilerOptions136  )137138  if (errors && errors.length) {139    return {140      ast,141      code: `var render = function () {}\n` + `var staticRenderFns = []\n`,142      source,143      tips,144      errors145    }146  } else {147    // stripping `with` usage148    let code =149      `var __render__ = ${prefixIdentifiers(150        `function render(${isFunctional ? `_c,_vm` : ``}){${render}\n}`,151        isFunctional,152        isTS,153        transpileOptions,154        bindings155      )}\n` +156      `var __staticRenderFns__ = [${staticRenderFns.map(code =>157        prefixIdentifiers(158          `function (${isFunctional ? `_c,_vm` : ``}){${code}\n}`,159          isFunctional,160          isTS,161          transpileOptions,162          bindings163        )164      )}]` +165      `\n`166167    // #23 we use __render__ to avoid `render` not being prefixed by the168    // transpiler when stripping with, but revert it back to `render` to169    // maintain backwards compat170    code = code.replace(/\s__(render|staticRenderFns)__\s/g, ' $1 ')171172    if (!isProduction) {173      // mark with stripped (this enables Vue to use correct runtime proxy174      // detection)175      code += `render._withStripped = true`176177      if (prettify) {178        try {179          code = require('prettier').format(code, {180            semi: false,181            parser: 'babel'182          })183        } catch (e: any) {184          if (e.code === 'MODULE_NOT_FOUND') {185            tips.push(186              'The `prettify` option is on, but the dependency `prettier` is not found.\n' +187                'Please either turn off `prettify` or manually install `prettier`.'188            )189          }190          tips.push(191            `Failed to prettify component ${options.filename} template source after compilation.`192          )193        }194      }195    }196197    return {198      ast,199      code,200      source,201      tips,202      errors203    }204  }205}

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.