]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-sfc): support module string names syntax (#7428)
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Tue, 28 Mar 2023 08:28:06 +0000 (16:28 +0800)
committerGitHub <noreply@github.com>
Tue, 28 Mar 2023 08:28:06 +0000 (16:28 +0800)
https://github.com/tc39/ecma262/pull/2154

packages/compiler-core/src/babelUtils.ts
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
packages/compiler-sfc/__tests__/compileScript.spec.ts
packages/compiler-sfc/src/compileScript.ts

index 5ddbc1ea4124444200ba7c56742c8166c99517a4..52175ef48b16c23ecbc7e465ca0f4faf499db81c 100644 (file)
@@ -6,7 +6,10 @@ import type {
   Function,
   ObjectProperty,
   BlockStatement,
-  Program
+  Program,
+  ImportDefaultSpecifier,
+  ImportNamespaceSpecifier,
+  ImportSpecifier
 } from '@babel/types'
 import { walk } from 'estree-walker'
 
@@ -243,6 +246,17 @@ export const isStaticProperty = (node: Node): node is ObjectProperty =>
 export const isStaticPropertyKey = (node: Node, parent: Node) =>
   isStaticProperty(parent) && parent.key === node
 
+export function getImportedName(
+  specifier: ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier
+) {
+  if (specifier.type === 'ImportSpecifier')
+    return specifier.imported.type === 'Identifier'
+      ? specifier.imported.name
+      : specifier.imported.value
+  else if (specifier.type === 'ImportNamespaceSpecifier') return '*'
+  return 'default'
+}
+
 /**
  * Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts
  * To avoid runtime dependency on @babel/types (which includes process references)
index 6220f860f16571bf0c140d79353880b7ddc173ef..b7a13e568510a10767ee486fadab199543b0fef5 100644 (file)
@@ -1027,6 +1027,20 @@ return { ref }
 }"
 `;
 
+exports[`SFC compile <script setup> > imports > should support module string names syntax 1`] = `
+"import { \\"😏\\" as foo } from './foo'
+      
+export default {
+  setup(__props, { expose }) {
+  expose();
+
+        
+return { get foo() { return foo } }
+}
+
+}"
+`;
+
 exports[`SFC compile <script setup> > inlineTemplate mode > avoid unref() when necessary 1`] = `
 "import { unref as _unref, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, withCtx as _withCtx, createVNode as _createVNode, createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
 
index 84a45debfe77910237651cd6923c4f2e1e664950..8f96ecc11c53a944b3ab8a1ed7198be70271faab 100644 (file)
@@ -515,6 +515,21 @@ defineExpose({ foo: 123 })
         })
       })
     })
+
+    test('should support module string names syntax', () => {
+      const { content, bindings } = compile(`
+      <script>
+        import { "😏" as foo } from './foo'
+      </script>
+      <script setup>
+        import { "😏" as foo } from './foo'
+      </script>
+    `)
+      assertCode(content)
+      expect(bindings).toStrictEqual({
+        foo: BindingTypes.SETUP_MAYBE_REF
+      })
+    })
   })
 
   // in dev mode, declared bindings are returned as an object from setup()
index c9fe242b25f71e098f591e4f791ecc75791493ec..e2e129924e3d68873cafefb4fbffe55ae099f0a9 100644 (file)
@@ -10,6 +10,7 @@ import {
   SimpleExpressionNode,
   isFunctionType,
   walkIdentifiers,
+  getImportedName,
   unwrapTSNode
 } from '@vue/compiler-dom'
 import { DEFAULT_FILENAME, SFCDescriptor, SFCScriptBlock } from './parse'
@@ -380,7 +381,7 @@ export function compileScript(
   function registerUserImport(
     source: string,
     local: string,
-    imported: string | false,
+    imported: string,
     isType: boolean,
     isFromSetup: boolean,
     needTemplateUsageCheck: boolean
@@ -400,7 +401,7 @@ export function compileScript(
 
     userImports[local] = {
       isType,
-      imported: imported || 'default',
+      imported,
       local,
       source,
       isFromSetup,
@@ -1002,10 +1003,7 @@ export function compileScript(
       if (node.type === 'ImportDeclaration') {
         // record imports for dedupe
         for (const specifier of node.specifiers) {
-          const imported =
-            specifier.type === 'ImportSpecifier' &&
-            specifier.imported.type === 'Identifier' &&
-            specifier.imported.name
+          const imported = getImportedName(specifier)
           registerUserImport(
             node.source.value,
             specifier.local.name,
@@ -1047,13 +1045,7 @@ export function compileScript(
       for (let i = 0; i < node.specifiers.length; i++) {
         const specifier = node.specifiers[i]
         const local = specifier.local.name
-        let imported =
-          specifier.type === 'ImportSpecifier' &&
-          specifier.imported.type === 'Identifier' &&
-          specifier.imported.name
-        if (specifier.type === 'ImportNamespaceSpecifier') {
-          imported = '*'
-        }
+        const imported = getImportedName(specifier)
         const source = node.source.value
         const existing = userImports[local]
         if (