feat(compiler-sfc): support import attributes and `using` syntax (#8786)

This commit is contained in:
三咲智子 Kevin Deng 2023-12-08 15:22:27 +08:00 committed by GitHub
parent 0dc875d53e
commit 5b2bd1df78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 4 deletions

View File

@ -1483,3 +1483,31 @@ _sfc_.setup = __setup__
: __injectCSSVars__ : __injectCSSVars__
" "
`; `;
exports[`SFC genDefaultAs > parser plugins > import attributes (user override for deprecated syntax) 1`] = `
"import { foo } from './foo.js' assert { type: 'foobar' }
export default {
setup(__props, { expose: __expose }) {
__expose();
return { get foo() { return foo } }
}
}"
`;
exports[`SFC genDefaultAs > parser plugins > import attributes 1`] = `
"import { foo } from './foo.js' with { type: 'foobar' }
export default {
setup(__props, { expose: __expose }) {
__expose();
return { get foo() { return foo } }
}
}"
`;

View File

@ -1600,4 +1600,38 @@ describe('SFC genDefaultAs', () => {
foo: BindingTypes.SETUP_REF foo: BindingTypes.SETUP_REF
}) })
}) })
describe('parser plugins', () => {
test('import attributes', () => {
const { content } = compile(`
<script setup>
import { foo } from './foo.js' with { type: 'foobar' }
</script>
`)
assertCode(content)
expect(() =>
compile(`
<script setup>
import { foo } from './foo.js' assert { type: 'foobar' }
</script>`)
).toThrow()
})
test('import attributes (user override for deprecated syntax)', () => {
const { content } = compile(
`
<script setup>
import { foo } from './foo.js' assert { type: 'foobar' }
</script>
`,
{
babelParserPlugins: [
['importAttributes', { deprecatedAssertSyntax: true }]
]
}
)
assertCode(content)
})
})
}) })

View File

@ -28,7 +28,10 @@ export function assertCode(code: string) {
try { try {
babelParse(code, { babelParse(code, {
sourceType: 'module', sourceType: 'module',
plugins: ['typescript'] plugins: [
'typescript',
['importAttributes', { deprecatedAssertSyntax: true }]
]
}) })
} catch (e: any) { } catch (e: any) {
console.log(code) console.log(code)

View File

@ -2,6 +2,7 @@ import { parse } from '@babel/parser'
import MagicString from 'magic-string' import MagicString from 'magic-string'
import type { ParserPlugin } from '@babel/parser' import type { ParserPlugin } from '@babel/parser'
import type { Identifier, Statement } from '@babel/types' import type { Identifier, Statement } from '@babel/types'
import { resolveParserPlugins } from './script/context'
export function rewriteDefault( export function rewriteDefault(
input: string, input: string,
@ -10,7 +11,7 @@ export function rewriteDefault(
): string { ): string {
const ast = parse(input, { const ast = parse(input, {
sourceType: 'module', sourceType: 'module',
plugins: parserPlugins plugins: resolveParserPlugins('js', parserPlugins)
}).program.body }).program.body
const s = new MagicString(input) const s = new MagicString(input)

View File

@ -1,6 +1,6 @@
import { CallExpression, Node, ObjectPattern, Program } from '@babel/types' import { CallExpression, Node, ObjectPattern, Program } from '@babel/types'
import { SFCDescriptor } from '../parse' import { SFCDescriptor } from '../parse'
import { generateCodeFrame } from '@vue/shared' import { generateCodeFrame, isArray } from '@vue/shared'
import { parse as babelParse, ParserPlugin } from '@babel/parser' import { parse as babelParse, ParserPlugin } from '@babel/parser'
import { ImportBinding, SFCScriptCompileOptions } from '../compileScript' import { ImportBinding, SFCScriptCompileOptions } from '../compileScript'
import { PropsDestructureBindings } from './defineProps' import { PropsDestructureBindings } from './defineProps'
@ -155,6 +155,17 @@ export function resolveParserPlugins(
dts = false dts = false
) { ) {
const plugins: ParserPlugin[] = [] const plugins: ParserPlugin[] = []
if (
!userPlugins ||
!userPlugins.some(
p =>
p === 'importAssertions' ||
p === 'importAttributes' ||
(isArray(p) && p[0] === 'importAttributes')
)
) {
plugins.push('importAttributes')
}
if (lang === 'jsx' || lang === 'tsx') { if (lang === 'jsx' || lang === 'tsx') {
plugins.push('jsx') plugins.push('jsx')
} else if (userPlugins) { } else if (userPlugins) {
@ -163,7 +174,7 @@ export function resolveParserPlugins(
userPlugins = userPlugins.filter(p => p !== 'jsx') userPlugins = userPlugins.filter(p => p !== 'jsx')
} }
if (lang === 'ts' || lang === 'tsx') { if (lang === 'ts' || lang === 'tsx') {
plugins.push(['typescript', { dts }]) plugins.push(['typescript', { dts }], 'explicitResourceManagement')
if (!userPlugins || !userPlugins.includes('decorators')) { if (!userPlugins || !userPlugins.includes('decorators')) {
plugins.push('decorators-legacy') plugins.push('decorators-legacy')
} }