@@ -113,7 +113,7 @@ export interface SFCScriptCompileOptions {
113
113
templateOptions ?: Partial < SFCTemplateCompileOptions >
114
114
}
115
115
116
- interface ImportBinding {
116
+ export interface ImportBinding {
117
117
isType : boolean
118
118
imported : string
119
119
source : string
@@ -335,11 +335,7 @@ export function compileScript(
335
335
336
336
let isUsedInTemplate = true
337
337
if ( isTS && sfc . template && ! sfc . template . src && ! sfc . template . lang ) {
338
- isUsedInTemplate = new RegExp (
339
- // #4274 escape $ since it's a special char in regex
340
- // (and is the only regex special char that is valid in identifiers)
341
- `[^\\w$_]${ local . replace ( / \$ / g, '\\$' ) } [^\\w$_]`
342
- ) . test ( resolveTemplateUsageCheckString ( sfc ) )
338
+ isUsedInTemplate = isImportUsed ( local , sfc )
343
339
}
344
340
345
341
userImports [ local ] = {
@@ -1441,6 +1437,7 @@ export function compileScript(
1441
1437
return {
1442
1438
...scriptSetup ,
1443
1439
bindings : bindingMetadata ,
1440
+ imports : userImports ,
1444
1441
content : s . toString ( ) ,
1445
1442
map : genSourceMap
1446
1443
? ( s . generateMap ( {
@@ -1960,7 +1957,7 @@ function getObjectOrArrayExpressionKeys(value: Node): string[] {
1960
1957
1961
1958
const templateUsageCheckCache = createCache < string > ( )
1962
1959
1963
- export function resolveTemplateUsageCheckString ( sfc : SFCDescriptor ) {
1960
+ function resolveTemplateUsageCheckString ( sfc : SFCDescriptor ) {
1964
1961
const { content, ast } = sfc . template !
1965
1962
const cached = templateUsageCheckCache . get ( content )
1966
1963
if ( cached ) {
@@ -2018,3 +2015,40 @@ function stripTemplateString(str: string): string {
2018
2015
}
2019
2016
return ''
2020
2017
}
2018
+
2019
+ function isImportUsed ( local : string , sfc : SFCDescriptor ) : boolean {
2020
+ return new RegExp (
2021
+ // #4274 escape $ since it's a special char in regex
2022
+ // (and is the only regex special char that is valid in identifiers)
2023
+ `[^\\w$_]${ local . replace ( / \$ / g, '\\$' ) } [^\\w$_]`
2024
+ ) . test ( resolveTemplateUsageCheckString ( sfc ) )
2025
+ }
2026
+
2027
+ /**
2028
+ * Note: this comparison assumes the prev/next script are already identical,
2029
+ * and only checks the special case where <script setup lang="ts"> unused import
2030
+ * pruning result changes due to template changes.
2031
+ */
2032
+ export function hmrShouldReload (
2033
+ prevImports : Record < string , ImportBinding > ,
2034
+ next : SFCDescriptor
2035
+ ) : boolean {
2036
+ if (
2037
+ ! next . scriptSetup ||
2038
+ ( next . scriptSetup . lang !== 'ts' && next . scriptSetup . lang !== 'tsx' )
2039
+ ) {
2040
+ return false
2041
+ }
2042
+
2043
+ // for each previous import, check if its used status remain the same based on
2044
+ // the next descriptor's template
2045
+ for ( const key in prevImports ) {
2046
+ // if an import was previous unused, but now is used, we need to force
2047
+ // reload so that the script now includes that import.
2048
+ if ( ! prevImports [ key ] . isUsedInTemplate && isImportUsed ( key , next ) ) {
2049
+ return true
2050
+ }
2051
+ }
2052
+
2053
+ return false
2054
+ }
0 commit comments