mirror of https://github.com/vuejs/core.git
feat(compiler-sfc): support module string names syntax (#7428)
https://github.com/tc39/ecma262/pull/2154
This commit is contained in:
parent
d60e58c9f6
commit
0002567728
|
@ -6,7 +6,10 @@ import type {
|
||||||
Function,
|
Function,
|
||||||
ObjectProperty,
|
ObjectProperty,
|
||||||
BlockStatement,
|
BlockStatement,
|
||||||
Program
|
Program,
|
||||||
|
ImportDefaultSpecifier,
|
||||||
|
ImportNamespaceSpecifier,
|
||||||
|
ImportSpecifier
|
||||||
} from '@babel/types'
|
} from '@babel/types'
|
||||||
import { walk } from 'estree-walker'
|
import { walk } from 'estree-walker'
|
||||||
|
|
||||||
|
@ -243,6 +246,17 @@ export const isStaticProperty = (node: Node): node is ObjectProperty =>
|
||||||
export const isStaticPropertyKey = (node: Node, parent: Node) =>
|
export const isStaticPropertyKey = (node: Node, parent: Node) =>
|
||||||
isStaticProperty(parent) && parent.key === 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
|
* 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)
|
* To avoid runtime dependency on @babel/types (which includes process references)
|
||||||
|
|
|
@ -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`] = `
|
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\\"
|
"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\\"
|
||||||
|
|
||||||
|
|
|
@ -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()
|
// in dev mode, declared bindings are returned as an object from setup()
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
SimpleExpressionNode,
|
SimpleExpressionNode,
|
||||||
isFunctionType,
|
isFunctionType,
|
||||||
walkIdentifiers,
|
walkIdentifiers,
|
||||||
|
getImportedName,
|
||||||
unwrapTSNode
|
unwrapTSNode
|
||||||
} from '@vue/compiler-dom'
|
} from '@vue/compiler-dom'
|
||||||
import { DEFAULT_FILENAME, SFCDescriptor, SFCScriptBlock } from './parse'
|
import { DEFAULT_FILENAME, SFCDescriptor, SFCScriptBlock } from './parse'
|
||||||
|
@ -380,7 +381,7 @@ export function compileScript(
|
||||||
function registerUserImport(
|
function registerUserImport(
|
||||||
source: string,
|
source: string,
|
||||||
local: string,
|
local: string,
|
||||||
imported: string | false,
|
imported: string,
|
||||||
isType: boolean,
|
isType: boolean,
|
||||||
isFromSetup: boolean,
|
isFromSetup: boolean,
|
||||||
needTemplateUsageCheck: boolean
|
needTemplateUsageCheck: boolean
|
||||||
|
@ -400,7 +401,7 @@ export function compileScript(
|
||||||
|
|
||||||
userImports[local] = {
|
userImports[local] = {
|
||||||
isType,
|
isType,
|
||||||
imported: imported || 'default',
|
imported,
|
||||||
local,
|
local,
|
||||||
source,
|
source,
|
||||||
isFromSetup,
|
isFromSetup,
|
||||||
|
@ -1002,10 +1003,7 @@ export function compileScript(
|
||||||
if (node.type === 'ImportDeclaration') {
|
if (node.type === 'ImportDeclaration') {
|
||||||
// record imports for dedupe
|
// record imports for dedupe
|
||||||
for (const specifier of node.specifiers) {
|
for (const specifier of node.specifiers) {
|
||||||
const imported =
|
const imported = getImportedName(specifier)
|
||||||
specifier.type === 'ImportSpecifier' &&
|
|
||||||
specifier.imported.type === 'Identifier' &&
|
|
||||||
specifier.imported.name
|
|
||||||
registerUserImport(
|
registerUserImport(
|
||||||
node.source.value,
|
node.source.value,
|
||||||
specifier.local.name,
|
specifier.local.name,
|
||||||
|
@ -1047,13 +1045,7 @@ export function compileScript(
|
||||||
for (let i = 0; i < node.specifiers.length; i++) {
|
for (let i = 0; i < node.specifiers.length; i++) {
|
||||||
const specifier = node.specifiers[i]
|
const specifier = node.specifiers[i]
|
||||||
const local = specifier.local.name
|
const local = specifier.local.name
|
||||||
let imported =
|
const imported = getImportedName(specifier)
|
||||||
specifier.type === 'ImportSpecifier' &&
|
|
||||||
specifier.imported.type === 'Identifier' &&
|
|
||||||
specifier.imported.name
|
|
||||||
if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
||||||
imported = '*'
|
|
||||||
}
|
|
||||||
const source = node.source.value
|
const source = node.source.value
|
||||||
const existing = userImports[local]
|
const existing = userImports[local]
|
||||||
if (
|
if (
|
||||||
|
|
Loading…
Reference in New Issue