Skip to content

Commit f855ccb

Browse files
committed
fix(compiler-sfc): fix import usage check in template strings in expressions
fix #4340
1 parent ad66295 commit f855ccb

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,15 @@ return { x }
206206
207207
exports[`SFC compile <script setup> imports imports not used in <template> should not be exposed 1`] = `
208208
"import { defineComponent as _defineComponent } from 'vue'
209-
import { FooBar, FooBaz, FooQux, vMyDir, x, y, z, x$y, Last } from './x'
209+
import { FooBar, FooBaz, FooQux, vMyDir, x, y, z, x$y, VAR, VAR2, VAR3, Last } from './x'
210210
211211
export default _defineComponent({
212212
setup(__props, { expose }) {
213213
expose()
214214
215215
const fooBar: FooBar = 1
216216
217-
return { fooBar, FooBaz, FooQux, vMyDir, x, z, x$y, Last }
217+
return { fooBar, FooBaz, FooQux, vMyDir, x, z, x$y, VAR, VAR3, Last }
218218
}
219219
220220
})"

packages/compiler-sfc/__tests__/compileScript.spec.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -213,27 +213,29 @@ defineExpose({ foo: 123 })
213213
test('imports not used in <template> should not be exposed', () => {
214214
const { content } = compile(`
215215
<script setup lang="ts">
216-
import { FooBar, FooBaz, FooQux, vMyDir, x, y, z, x$y, Last } from './x'
216+
import { FooBar, FooBaz, FooQux, vMyDir, x, y, z, x$y, VAR, VAR2, VAR3, Last } from './x'
217217
const fooBar: FooBar = 1
218218
</script>
219219
<template>
220220
<FooBaz v-my-dir>{{ x }} {{ yy }} {{ x$y }}</FooBaz>
221221
<foo-qux/>
222222
<div :id="z + 'y'">FooBar</div>
223+
{{ \`\${VAR}VAR2\${VAR3}\` }}
223224
<Last/>
224225
</template>
225226
`)
226-
assertCode(content)
227227
// FooBar: should not be matched by plain text
228228
// FooBaz: used as PascalCase component
229229
// FooQux: used as kebab-case component
230230
// vMyDir: used as directive v-my-dir
231231
// x: used in interpolation
232232
// y: should not be matched by {{ yy }} or 'y' in binding exps
233233
// x$y: #4274 should escape special chars when creating Regex
234+
// VAR & VAR3: #4340 interpolations in tempalte strings
234235
expect(content).toMatch(
235-
`return { fooBar, FooBaz, FooQux, vMyDir, x, z, x$y, Last }`
236+
`return { fooBar, FooBaz, FooQux, vMyDir, x, z, x$y, VAR, VAR3, Last }`
236237
)
238+
assertCode(content)
237239
})
238240
})
239241

packages/compiler-sfc/src/compileScript.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -2242,5 +2242,15 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
22422242
}
22432243

22442244
function stripStrings(exp: string) {
2245-
return exp.replace(/'[^']+'|"[^"]+"|`[^`]+`/g, '')
2245+
return exp
2246+
.replace(/'[^']+'|"[^"]+"/g, '')
2247+
.replace(/`[^`]+`/g, stripTemplateString)
2248+
}
2249+
2250+
function stripTemplateString(str: string): string {
2251+
const interpMatch = str.match(/\${[^}]+}/g)
2252+
if (interpMatch) {
2253+
return interpMatch.map(m => m.slice(2, -1)).join(',')
2254+
}
2255+
return ''
22462256
}

0 commit comments

Comments
 (0)