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.