fix(compiler-sfc): removeSpecifier issue when removing initial imports (script-setup) (#2729)

This commit is contained in:
Matias Capeletto 2021-02-13 10:06:34 +01:00 committed by GitHub
parent 22b382a714
commit 6d762a84ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 8 deletions

View File

@ -164,6 +164,25 @@ return { x }
}" }"
`; `;
exports[`SFC compile <script setup> imports should allow defineProps/Emit at the start of imports 1`] = `
"import { ref } from 'vue'
export default {
expose: [],
props: ['foo'],
emits: ['bar'],
setup(__props) {
const r = ref(0)
return { r, ref }
}
}"
`;
exports[`SFC compile <script setup> imports should extract comment for import or type declarations 1`] = ` exports[`SFC compile <script setup> imports should extract comment for import or type declarations 1`] = `
"import a from 'a' // comment "import a from 'a' // comment
import b from 'b' import b from 'b'

View File

@ -141,6 +141,18 @@ const myEmit = defineEmit(['foo', 'bar'])
) )
}) })
// #2740
test('should allow defineProps/Emit at the start of imports', () => {
assertCode(
compile(`<script setup>
import { defineProps, defineEmit, ref } from 'vue'
defineProps(['foo'])
defineEmit(['bar'])
const r = ref(0)
</script>`).content
)
})
test('dedupe between user & helper', () => { test('dedupe between user & helper', () => {
const { content } = compile(` const { content } = compile(`
<script setup> <script setup>

View File

@ -597,19 +597,23 @@ export function compileScript(
// dedupe imports // dedupe imports
let removed = 0 let removed = 0
let prev: Node | undefined, next: Node | undefined const removeSpecifier = (i: number) => {
const removeSpecifier = (node: Node) => { const removeLeft = i > removed
removed++ removed++
const current = node.specifiers[i]
const next = node.specifiers[i + 1]
s.remove( s.remove(
prev ? prev.end! + startOffset : node.start! + startOffset, removeLeft
next && !prev ? next.start! + startOffset : node.end! + startOffset ? node.specifiers[i - 1].end! + startOffset
: current.start! + startOffset,
next && !removeLeft
? next.start! + startOffset
: current.end! + startOffset
) )
} }
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]
prev = node.specifiers[i - 1]
next = node.specifiers[i + 1]
const local = specifier.local.name const local = specifier.local.name
const imported = const imported =
specifier.type === 'ImportSpecifier' && specifier.type === 'ImportSpecifier' &&
@ -621,11 +625,11 @@ export function compileScript(
source === 'vue' && source === 'vue' &&
(imported === DEFINE_PROPS || imported === DEFINE_EMIT) (imported === DEFINE_PROPS || imported === DEFINE_EMIT)
) { ) {
removeSpecifier(specifier) removeSpecifier(i)
} else if (existing) { } else if (existing) {
if (existing.source === source && existing.imported === imported) { if (existing.source === source && existing.imported === imported) {
// already imported in <script setup>, dedupe // already imported in <script setup>, dedupe
removeSpecifier(specifier) removeSpecifier(i)
} else { } else {
error(`different imports aliased to same local name.`, specifier) error(`different imports aliased to same local name.`, specifier)
} }