Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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`] = `
"import a from 'a' // comment
import b from 'b'
Expand Down
12 changes: 12 additions & 0 deletions packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ const myEmit = defineEmit(['foo', 'bar'])
)
})

// #2740
test('should allow defineProps/Emit at the start of imports', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to have a comment linking to the PR/issue here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a reference to #2740, following the convention that I saw in other tests (not the full link, just the number)

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', () => {
const { content } = compile(`
<script setup>
Expand Down
20 changes: 12 additions & 8 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,19 +597,23 @@ export function compileScript(

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