wip: more consistent compiler-sfc usage + inline mode for ssr

This commit is contained in:
Evan You
2020-11-20 14:22:51 -05:00
parent 58227e88e9
commit 8ac2241b22
18 changed files with 213 additions and 93 deletions

View File

@@ -167,6 +167,7 @@ export function compileScript(
let optionsArg: ObjectExpression | undefined
let optionsType: TSTypeLiteral | undefined
let hasAwait = false
let hasInlinedSsrRenderFn = false
// context types to generate
let propsType = `{}`
let emitType = `(e: string, ...args: any[]) => void`
@@ -820,15 +821,24 @@ export function compileScript(
// 10. generate return statement
let returned
if (options.inlineTemplate) {
if (sfc.template) {
if (sfc.template && !sfc.template.src) {
if (options.templateOptions && options.templateOptions.ssr) {
hasInlinedSsrRenderFn = true
}
// inline render function mode - we are going to compile the template and
// inline it right here
const { code, ast, preamble, tips, errors } = compileTemplate({
...options.templateOptions,
filename,
source: sfc.template.content,
inMap: sfc.template.map,
...options.templateOptions,
id: scopeId,
scoped: sfc.styles.some(s => s.scoped),
isProd: options.isProd,
ssrCssVars: sfc.cssVars,
compilerOptions: {
...(options.templateOptions &&
options.templateOptions.compilerOptions),
inline: true,
isTS,
bindingMetadata
@@ -883,6 +893,9 @@ export function compileScript(
// 11. finalize default export
// expose: [] makes <script setup> components "closed" by default.
let runtimeOptions = `\n expose: [],`
if (hasInlinedSsrRenderFn) {
runtimeOptions += `\n __ssrInlineRender: true,`
}
if (optionsArg) {
runtimeOptions += `\n ${scriptSetup.content
.slice(optionsArg.start! + 1, optionsArg.end! - 1)

View File

@@ -20,15 +20,19 @@ export interface SFCStyleCompileOptions {
source: string
filename: string
id: string
map?: RawSourceMap
scoped?: boolean
trim?: boolean
isProd?: boolean
inMap?: RawSourceMap
preprocessLang?: PreprocessLang
preprocessOptions?: any
preprocessCustomRequire?: (id: string) => any
postcssOptions?: any
postcssPlugins?: any[]
/**
* @deprecated
*/
map?: RawSourceMap
}
export interface SFCAsyncStyleCompileOptions extends SFCStyleCompileOptions {
@@ -92,16 +96,21 @@ export function doCompileStyle(
} = options
const preprocessor = preprocessLang && processors[preprocessLang]
const preProcessedSource = preprocessor && preprocess(options, preprocessor)
const map = preProcessedSource ? preProcessedSource.map : options.map
const map = preProcessedSource
? preProcessedSource.map
: options.inMap || options.map
const source = preProcessedSource ? preProcessedSource.code : options.source
const shortId = id.replace(/^data-v-/, '')
const longId = `data-v-${shortId}`
const plugins = (postcssPlugins || []).slice()
plugins.unshift(cssVarsPlugin({ id, isProd }))
plugins.unshift(cssVarsPlugin({ id: shortId, isProd }))
if (trim) {
plugins.push(trimPlugin())
}
if (scoped) {
plugins.push(scopedPlugin(id))
plugins.push(scopedPlugin(longId))
}
let cssModules: Record<string, string> | undefined
if (modules) {

View File

@@ -23,6 +23,7 @@ import * as CompilerDOM from '@vue/compiler-dom'
import * as CompilerSSR from '@vue/compiler-ssr'
import consolidate from 'consolidate'
import { warnOnce } from './warn'
import { genCssVarsFromList } from './cssVars'
export interface TemplateCompiler {
compile(template: string, options: CompilerOptions): CodegenResult
@@ -42,7 +43,11 @@ export interface SFCTemplateCompileResults {
export interface SFCTemplateCompileOptions {
source: string
filename: string
id: string
scoped?: boolean
isProd?: boolean
ssr?: boolean
ssrCssVars?: string[]
inMap?: RawSourceMap
compiler?: TemplateCompiler
compilerOptions?: CompilerOptions
@@ -151,9 +156,13 @@ export function compileTemplate(
function doCompileTemplate({
filename,
id,
scoped,
inMap,
source,
ssr = false,
ssrCssVars,
isProd = false,
compiler = ssr ? (CompilerSSR as TemplateCompiler) : CompilerDOM,
compilerOptions = {},
transformAssetUrls
@@ -171,19 +180,30 @@ function doCompileTemplate({
nodeTransforms = [transformAssetUrl, transformSrcset]
}
if (ssr && compilerOptions.ssrCssVars == null) {
if (ssr && !ssrCssVars) {
warnOnce(
`compileTemplate is called with \`ssr: true\` but no ` +
`corresponding \`ssrCssVars\` option. The value can be generated by ` +
`calling \`generateCssVars(sfcDescriptor, scopeId, isProduction)\`.`
`corresponding \`cssVars\` option.\`.`
)
}
if (!id) {
warnOnce(`compileTemplate now requires the \`id\` option.\`.`)
id = ''
}
const shortId = id.replace(/^data-v-/, '')
const longId = `data-v-${shortId}`
let { code, ast, preamble, map } = compiler.compile(source, {
mode: 'module',
prefixIdentifiers: true,
hoistStatic: true,
cacheHandlers: true,
ssrCssVars:
ssr && ssrCssVars && ssrCssVars.length
? genCssVarsFromList(ssrCssVars, shortId, isProd)
: '',
scopeId: scoped ? longId : undefined,
...compilerOptions,
nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []),
filename,

View File

@@ -16,26 +16,13 @@ import hash from 'hash-sum'
export const CSS_VARS_HELPER = `useCssVars`
export const cssVarRE = /\bv-bind\(\s*(?:'([^']+)'|"([^"]+)"|([^'"][^)]*))\s*\)/g
/**
* Given an SFC descriptor, generate the CSS variables object string that can be
* passed to `compileTemplate` as `compilerOptions.ssrCssVars`.
* @public
*/
export function generateCssVars(
sfc: SFCDescriptor,
id: string,
isProd: boolean
): string {
return sfc.cssVars.length ? genCssVarsFromList(sfc.cssVars, id, isProd) : ''
}
function genCssVarsFromList(
export function genCssVarsFromList(
vars: string[],
id: string,
isProd: boolean
): string {
return `{\n ${vars
.map(v => `"${genVarName(id, v, isProd)}": (${v})`)
.map(key => `"${genVarName(id, key, isProd)}": (${key})`)
.join(',\n ')}\n}`
}
@@ -68,12 +55,11 @@ export const cssVarsPlugin = postcss.plugin<CssVarsPluginOptions>(
'vue-scoped',
opts => (root: Root) => {
const { id, isProd } = opts!
const shortId = id.replace(/^data-v-/, '')
root.walkDecls(decl => {
// rewrite CSS variables
if (cssVarRE.test(decl.value)) {
decl.value = decl.value.replace(cssVarRE, (_, $1, $2, $3) => {
return `var(--${genVarName(shortId, $1 || $2 || $3, isProd)})`
return `var(--${genVarName(id, $1 || $2 || $3, isProd)})`
})
}
})

View File

@@ -5,7 +5,6 @@ export { compileStyle, compileStyleAsync } from './compileStyle'
export { compileScript } from './compileScript'
export { rewriteDefault } from './rewriteDefault'
export { generateCodeFrame } from '@vue/compiler-core'
export { generateCssVars } from './cssVars'
// Types
export {