]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-sfc): support import attributes and `using` syntax (#8786)
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Fri, 8 Dec 2023 07:22:27 +0000 (15:22 +0800)
committerGitHub <noreply@github.com>
Fri, 8 Dec 2023 07:22:27 +0000 (15:22 +0800)
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
packages/compiler-sfc/__tests__/compileScript.spec.ts
packages/compiler-sfc/__tests__/utils.ts
packages/compiler-sfc/src/rewriteDefault.ts
packages/compiler-sfc/src/script/context.ts

index b2c6904fbacce792f3d7c15037f120edf35f62cd..01267cd42c74c6990cd1876a073303e14bb00bbd 100644 (file)
@@ -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 } }
+}
+
+}"
+`;
index 6eef8d51e636894e8bf8860575c63ff19d672005..96338b022f313ae54aaf2c015f15a74f38f22a53 100644 (file)
@@ -1600,4 +1600,38 @@ describe('SFC genDefaultAs', () => {
       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)
+    })
+  })
 })
index 13e12d765a21caeb3e4467009c3d8a20e26876f3..5fcc6f0b7f88e22c5bc7f747d04fd0eeaff4e342 100644 (file)
@@ -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)
index 277eedce011944466f67bfd8e399d6dc212b647a..cb1826b4a8341996b979392d46af93e895c47f13 100644 (file)
@@ -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)
 
index b05b8d910eefca18875d283feabd9770e48c0e9b..900cf1092603c561150bb8017d21a890f1094444 100644 (file)
@@ -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')
     }