wip: more consistent compiler-sfc usage + inline mode for ssr
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)})`
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user