wip: support inherit-attrs="false" on sfc <tempalte>

This commit is contained in:
Evan You 2020-11-24 15:28:35 -05:00
parent 47d73c23e1
commit faed98972c
4 changed files with 75 additions and 26 deletions

View File

@ -33,6 +33,27 @@ return { x }
export const n = 1" export const n = 1"
`; `;
exports[`SFC compile <script setup> <template inherit-attrs="false"> 1`] = `
"
const __default__ = {}
__default__.inheritAttrs = false
export default __default__"
`;
exports[`SFC compile <script setup> <template inherit-attrs="false"> 2`] = `
"export default {
expose: [],
inheritAttrs: false,
setup(__props) {
const a = 1
return { a }
}
}"
`;
exports[`SFC compile <script setup> defineEmit() 1`] = ` exports[`SFC compile <script setup> defineEmit() 1`] = `
"export default { "export default {
expose: [], expose: [],

View File

@ -70,6 +70,28 @@ const myEmit = defineEmit(['foo', 'bar'])
emits: ['foo', 'bar'],`) emits: ['foo', 'bar'],`)
}) })
test('<template inherit-attrs="false">', () => {
const { content } = compile(`
<script>
export default {}
</script>
<template inherit-attrs="false">
{{ a }}
</template>
`)
assertCode(content)
const { content: content2 } = compile(`
<script setup>
const a = 1
</script>
<template inherit-attrs="false">
{{ a }}
</template>
`)
assertCode(content2)
})
describe('<script> and <script setup> co-usage', () => { describe('<script> and <script setup> co-usage', () => {
test('script first', () => { test('script first', () => {
const { content } = compile(` const { content } = compile(`

View File

@ -25,9 +25,14 @@ import {
} from '@babel/types' } from '@babel/types'
import { walk } from 'estree-walker' import { walk } from 'estree-walker'
import { RawSourceMap } from 'source-map' import { RawSourceMap } from 'source-map'
import { CSS_VARS_HELPER, genCssVarsCode, injectCssVarsCalls } from './cssVars' import {
CSS_VARS_HELPER,
genCssVarsCode,
genNormalScriptCssVarsCode
} from './cssVars'
import { compileTemplate, SFCTemplateCompileOptions } from './compileTemplate' import { compileTemplate, SFCTemplateCompileOptions } from './compileTemplate'
import { warnExperimental, warnOnce } from './warn' import { warnExperimental, warnOnce } from './warn'
import { rewriteDefault } from './rewriteDefault'
const DEFINE_PROPS = 'defineProps' const DEFINE_PROPS = 'defineProps'
const DEFINE_EMIT = 'defineEmit' const DEFINE_EMIT = 'defineEmit'
@ -92,6 +97,8 @@ export function compileScript(
const scopeId = options.id ? options.id.replace(/^data-v-/, '') : '' const scopeId = options.id ? options.id.replace(/^data-v-/, '') : ''
const cssVars = sfc.cssVars const cssVars = sfc.cssVars
const hasInheritAttrsFlag =
sfc.template && sfc.template.attrs['inherit-attrs'] === 'false'
const scriptLang = script && script.lang const scriptLang = script && script.lang
const scriptSetupLang = scriptSetup && scriptSetup.lang const scriptSetupLang = scriptSetup && scriptSetup.lang
const isTS = scriptLang === 'ts' || scriptSetupLang === 'ts' const isTS = scriptLang === 'ts' || scriptSetupLang === 'ts'
@ -113,18 +120,26 @@ export function compileScript(
sourceType: 'module' sourceType: 'module'
}).program.body }).program.body
const bindings = analyzeScriptBindings(scriptAst) const bindings = analyzeScriptBindings(scriptAst)
const needRewrite = cssVars.length || hasInheritAttrsFlag
let content = script.content
if (needRewrite) {
content = rewriteDefault(content, `__default__`, plugins)
if (cssVars.length) {
content += genNormalScriptCssVarsCode(
cssVars,
bindings,
scopeId,
!!options.isProd
)
}
if (hasInheritAttrsFlag) {
content += `__default__.inheritAttrs = false`
}
content += `\nexport default __default__`
}
return { return {
...script, ...script,
content: cssVars.length content,
? injectCssVarsCalls(
sfc,
cssVars,
bindings,
scopeId,
!!options.isProd,
plugins
)
: script.content,
bindings, bindings,
scriptAst scriptAst
} }
@ -922,6 +937,9 @@ export function compileScript(
// 11. finalize default export // 11. finalize default export
// expose: [] makes <script setup> components "closed" by default. // expose: [] makes <script setup> components "closed" by default.
let runtimeOptions = `\n expose: [],` let runtimeOptions = `\n expose: [],`
if (hasInheritAttrsFlag) {
runtimeOptions += `\n inheritAttrs: false,`
}
if (hasInlinedSsrRenderFn) { if (hasInlinedSsrRenderFn) {
runtimeOptions += `\n __ssrInlineRender: true,` runtimeOptions += `\n __ssrInlineRender: true,`
} }

View File

@ -8,8 +8,6 @@ import {
BindingMetadata BindingMetadata
} from '@vue/compiler-dom' } from '@vue/compiler-dom'
import { SFCDescriptor } from './parse' import { SFCDescriptor } from './parse'
import { rewriteDefault } from './rewriteDefault'
import { ParserPlugin } from '@babel/parser'
import postcss, { Root } from 'postcss' import postcss, { Root } from 'postcss'
import hash from 'hash-sum' import hash from 'hash-sum'
@ -96,22 +94,13 @@ export function genCssVarsCode(
// <script setup> already gets the calls injected as part of the transform // <script setup> already gets the calls injected as part of the transform
// this is only for single normal <script> // this is only for single normal <script>
export function injectCssVarsCalls( export function genNormalScriptCssVarsCode(
sfc: SFCDescriptor,
cssVars: string[], cssVars: string[],
bindings: BindingMetadata, bindings: BindingMetadata,
id: string, id: string,
isProd: boolean, isProd: boolean
parserPlugins: ParserPlugin[]
): string { ): string {
const script = rewriteDefault(
sfc.script!.content,
`__default__`,
parserPlugins
)
return ( return (
script +
`\nimport { ${CSS_VARS_HELPER} as _${CSS_VARS_HELPER} } from 'vue'\n` + `\nimport { ${CSS_VARS_HELPER} as _${CSS_VARS_HELPER} } from 'vue'\n` +
`const __injectCSSVars__ = () => {\n${genCssVarsCode( `const __injectCSSVars__ = () => {\n${genCssVarsCode(
cssVars, cssVars,
@ -122,7 +111,6 @@ export function injectCssVarsCalls(
`const __setup__ = __default__.setup\n` + `const __setup__ = __default__.setup\n` +
`__default__.setup = __setup__\n` + `__default__.setup = __setup__\n` +
` ? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }\n` + ` ? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }\n` +
` : __injectCSSVars__\n` + ` : __injectCSSVars__\n`
`export default __default__`
) )
} }