@@ -64,7 +64,7 @@ namespace ts.codefix {
64
64
const symbol = checker . getMergedSymbol ( skipAlias ( exportedSymbol , checker ) ) ;
65
65
const exportInfos = getAllReExportingModules ( sourceFile , symbol , moduleSymbol , symbolName , host , program , useAutoImportProvider ) ;
66
66
const preferTypeOnlyImport = ! ! usageIsTypeOnly && compilerOptions . importsNotUsedAsValues === ImportsNotUsedAsValues . Error ;
67
- const useRequire = shouldUseRequire ( sourceFile , compilerOptions ) ;
67
+ const useRequire = shouldUseRequire ( sourceFile , program ) ;
68
68
const fix = getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , symbolName , program , /*position*/ undefined , preferTypeOnlyImport , useRequire , host , preferences ) ;
69
69
addImport ( { fixes : [ fix ] , symbolName } ) ;
70
70
}
@@ -211,7 +211,7 @@ namespace ts.codefix {
211
211
) : { readonly moduleSpecifier : string , readonly codeAction : CodeAction } {
212
212
const compilerOptions = program . getCompilerOptions ( ) ;
213
213
const exportInfos = getAllReExportingModules ( sourceFile , exportedSymbol , moduleSymbol , symbolName , host , program , /*useAutoImportProvider*/ true ) ;
214
- const useRequire = shouldUseRequire ( sourceFile , compilerOptions ) ;
214
+ const useRequire = shouldUseRequire ( sourceFile , program ) ;
215
215
const preferTypeOnlyImport = compilerOptions . importsNotUsedAsValues === ImportsNotUsedAsValues . Error && ! isSourceFileJS ( sourceFile ) && isValidTypeOnlyAliasUseSite ( getTokenAtPosition ( sourceFile , position ) ) ;
216
216
const moduleSpecifier = first ( getNewImportInfos ( program , sourceFile , position , preferTypeOnlyImport , useRequire , exportInfos , host , preferences ) ) . moduleSpecifier ;
217
217
const fix = getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , symbolName , program , position , preferTypeOnlyImport , useRequire , host , preferences ) ;
@@ -362,10 +362,31 @@ namespace ts.codefix {
362
362
} ) ;
363
363
}
364
364
365
- function shouldUseRequire ( sourceFile : SourceFile , compilerOptions : CompilerOptions ) : boolean {
366
- return isSourceFileJS ( sourceFile )
367
- && ! sourceFile . externalModuleIndicator
368
- && ( ! ! sourceFile . commonJsModuleIndicator || getEmitModuleKind ( compilerOptions ) < ModuleKind . ES2015 ) ;
365
+ function shouldUseRequire ( sourceFile : SourceFile , program : Program ) : boolean {
366
+ // 1. TypeScript files don't use require variable declarations
367
+ if ( ! isSourceFileJS ( sourceFile ) ) {
368
+ return false ;
369
+ }
370
+
371
+ // 2. If the current source file is unambiguously CJS or ESM, go with that
372
+ if ( sourceFile . commonJsModuleIndicator && ! sourceFile . externalModuleIndicator ) return true ;
373
+ if ( sourceFile . externalModuleIndicator && ! sourceFile . commonJsModuleIndicator ) return false ;
374
+
375
+ // 3. If there's a tsconfig/jsconfig, use its module setting
376
+ const compilerOptions = program . getCompilerOptions ( ) ;
377
+ if ( compilerOptions . configFile ) {
378
+ return getEmitModuleKind ( compilerOptions ) < ModuleKind . ES2015 ;
379
+ }
380
+
381
+ // 4. Match the first other JS file in the program that's unambiguously CJS or ESM
382
+ for ( const otherFile of program . getSourceFiles ( ) ) {
383
+ if ( otherFile === sourceFile || ! isSourceFileJS ( otherFile ) || program . isSourceFileFromExternalLibrary ( otherFile ) ) continue ;
384
+ if ( otherFile . commonJsModuleIndicator && ! otherFile . externalModuleIndicator ) return true ;
385
+ if ( otherFile . externalModuleIndicator && ! otherFile . commonJsModuleIndicator ) return false ;
386
+ }
387
+
388
+ // 5. Literally nothing to go on
389
+ return true ;
369
390
}
370
391
371
392
function getNewImportInfos (
@@ -445,7 +466,7 @@ namespace ts.codefix {
445
466
const symbol = checker . getAliasedSymbol ( umdSymbol ) ;
446
467
const symbolName = umdSymbol . name ;
447
468
const exportInfos : readonly SymbolExportInfo [ ] = [ { moduleSymbol : symbol , importKind : getUmdImportKind ( sourceFile , program . getCompilerOptions ( ) ) , exportedSymbolIsTypeOnly : false } ] ;
448
- const useRequire = shouldUseRequire ( sourceFile , program . getCompilerOptions ( ) ) ;
469
+ const useRequire = shouldUseRequire ( sourceFile , program ) ;
449
470
const fixes = getFixForImport ( exportInfos , symbolName , isIdentifier ( token ) ? token . getStart ( sourceFile ) : undefined , /*preferTypeOnlyImport*/ false , useRequire , program , sourceFile , host , preferences ) ;
450
471
return { fixes, symbolName } ;
451
472
}
@@ -497,7 +518,7 @@ namespace ts.codefix {
497
518
498
519
const compilerOptions = program . getCompilerOptions ( ) ;
499
520
const preferTypeOnlyImport = compilerOptions . importsNotUsedAsValues === ImportsNotUsedAsValues . Error && isValidTypeOnlyAliasUseSite ( symbolToken ) ;
500
- const useRequire = shouldUseRequire ( sourceFile , compilerOptions ) ;
521
+ const useRequire = shouldUseRequire ( sourceFile , program ) ;
501
522
const exportInfos = getExportInfos ( symbolName , getMeaningFromLocation ( symbolToken ) , cancellationToken , sourceFile , program , useAutoImportProvider , host ) ;
502
523
const fixes = arrayFrom ( flatMapIterator ( exportInfos . entries ( ) , ( [ _ , exportInfos ] ) =>
503
524
getFixForImport ( exportInfos , symbolName , symbolToken . getStart ( sourceFile ) , preferTypeOnlyImport , useRequire , program , sourceFile , host , preferences ) ) ) ;
0 commit comments