diff --git a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
index b2c6904fbac..01267cd42c7 100644
--- a/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
@@ -1483,3 +1483,31 @@ _sfc_.setup = __setup__
: __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 } }
+}
+
+}"
+`;
diff --git a/packages/compiler-sfc/__tests__/compileScript.spec.ts b/packages/compiler-sfc/__tests__/compileScript.spec.ts
index 6eef8d51e63..96338b022f3 100644
--- a/packages/compiler-sfc/__tests__/compileScript.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript.spec.ts
@@ -1600,4 +1600,38 @@ describe('SFC genDefaultAs', () => {
foo: BindingTypes.SETUP_REF
})
})
+
+ describe('parser plugins', () => {
+ test('import attributes', () => {
+ const { content } = compile(`
+
+ `)
+ assertCode(content)
+
+ expect(() =>
+ compile(`
+ `)
+ ).toThrow()
+ })
+
+ test('import attributes (user override for deprecated syntax)', () => {
+ const { content } = compile(
+ `
+
+ `,
+ {
+ babelParserPlugins: [
+ ['importAttributes', { deprecatedAssertSyntax: true }]
+ ]
+ }
+ )
+ assertCode(content)
+ })
+ })
})
diff --git a/packages/compiler-sfc/__tests__/utils.ts b/packages/compiler-sfc/__tests__/utils.ts
index 13e12d765a2..5fcc6f0b7f8 100644
--- a/packages/compiler-sfc/__tests__/utils.ts
+++ b/packages/compiler-sfc/__tests__/utils.ts
@@ -28,7 +28,10 @@ export function assertCode(code: string) {
try {
babelParse(code, {
sourceType: 'module',
- plugins: ['typescript']
+ plugins: [
+ 'typescript',
+ ['importAttributes', { deprecatedAssertSyntax: true }]
+ ]
})
} catch (e: any) {
console.log(code)
diff --git a/packages/compiler-sfc/src/rewriteDefault.ts b/packages/compiler-sfc/src/rewriteDefault.ts
index 277eedce011..cb1826b4a83 100644
--- a/packages/compiler-sfc/src/rewriteDefault.ts
+++ b/packages/compiler-sfc/src/rewriteDefault.ts
@@ -2,6 +2,7 @@ import { parse } from '@babel/parser'
import MagicString from 'magic-string'
import type { ParserPlugin } from '@babel/parser'
import type { Identifier, Statement } from '@babel/types'
+import { resolveParserPlugins } from './script/context'
export function rewriteDefault(
input: string,
@@ -10,7 +11,7 @@ export function rewriteDefault(
): string {
const ast = parse(input, {
sourceType: 'module',
- plugins: parserPlugins
+ plugins: resolveParserPlugins('js', parserPlugins)
}).program.body
const s = new MagicString(input)
diff --git a/packages/compiler-sfc/src/script/context.ts b/packages/compiler-sfc/src/script/context.ts
index b05b8d910ee..900cf109260 100644
--- a/packages/compiler-sfc/src/script/context.ts
+++ b/packages/compiler-sfc/src/script/context.ts
@@ -1,6 +1,6 @@
import { CallExpression, Node, ObjectPattern, Program } from '@babel/types'
import { SFCDescriptor } from '../parse'
-import { generateCodeFrame } from '@vue/shared'
+import { generateCodeFrame, isArray } from '@vue/shared'
import { parse as babelParse, ParserPlugin } from '@babel/parser'
import { ImportBinding, SFCScriptCompileOptions } from '../compileScript'
import { PropsDestructureBindings } from './defineProps'
@@ -155,6 +155,17 @@ export function resolveParserPlugins(
dts = false
) {
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') {
plugins.push('jsx')
} else if (userPlugins) {
@@ -163,7 +174,7 @@ export function resolveParserPlugins(
userPlugins = userPlugins.filter(p => p !== 'jsx')
}
if (lang === 'ts' || lang === 'tsx') {
- plugins.push(['typescript', { dts }])
+ plugins.push(['typescript', { dts }], 'explicitResourceManagement')
if (!userPlugins || !userPlugins.includes('decorators')) {
plugins.push('decorators-legacy')
}