@@ -64,7 +64,7 @@ namespace ts.codefix {
6464 const symbol = checker . getMergedSymbol ( skipAlias ( exportedSymbol , checker ) ) ;
6565 const exportInfos = getAllReExportingModules ( sourceFile , symbol , moduleSymbol , symbolName , host , program , useAutoImportProvider ) ;
6666 const preferTypeOnlyImport = ! ! usageIsTypeOnly && compilerOptions . importsNotUsedAsValues === ImportsNotUsedAsValues . Error ;
67- const useRequire = shouldUseRequire ( sourceFile , compilerOptions ) ;
67+ const useRequire = shouldUseRequire ( sourceFile , program ) ;
6868 const fix = getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , symbolName , program , /*position*/ undefined , preferTypeOnlyImport , useRequire , host , preferences ) ;
6969 addImport ( { fixes : [ fix ] , symbolName } ) ;
7070 }
@@ -211,7 +211,7 @@ namespace ts.codefix {
211211 ) : { readonly moduleSpecifier : string , readonly codeAction : CodeAction } {
212212 const compilerOptions = program . getCompilerOptions ( ) ;
213213 const exportInfos = getAllReExportingModules ( sourceFile , exportedSymbol , moduleSymbol , symbolName , host , program , /*useAutoImportProvider*/ true ) ;
214- const useRequire = shouldUseRequire ( sourceFile , compilerOptions ) ;
214+ const useRequire = shouldUseRequire ( sourceFile , program ) ;
215215 const preferTypeOnlyImport = compilerOptions . importsNotUsedAsValues === ImportsNotUsedAsValues . Error && ! isSourceFileJS ( sourceFile ) && isValidTypeOnlyAliasUseSite ( getTokenAtPosition ( sourceFile , position ) ) ;
216216 const moduleSpecifier = first ( getNewImportInfos ( program , sourceFile , position , preferTypeOnlyImport , useRequire , exportInfos , host , preferences ) ) . moduleSpecifier ;
217217 const fix = getImportFixForSymbol ( sourceFile , exportInfos , moduleSymbol , symbolName , program , position , preferTypeOnlyImport , useRequire , host , preferences ) ;
@@ -362,10 +362,31 @@ namespace ts.codefix {
362362 } ) ;
363363 }
364364
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 ;
369390 }
370391
371392 function getNewImportInfos (
@@ -445,7 +466,7 @@ namespace ts.codefix {
445466 const symbol = checker . getAliasedSymbol ( umdSymbol ) ;
446467 const symbolName = umdSymbol . name ;
447468 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 ) ;
449470 const fixes = getFixForImport ( exportInfos , symbolName , isIdentifier ( token ) ? token . getStart ( sourceFile ) : undefined , /*preferTypeOnlyImport*/ false , useRequire , program , sourceFile , host , preferences ) ;
450471 return { fixes, symbolName } ;
451472 }
@@ -497,7 +518,7 @@ namespace ts.codefix {
497518
498519 const compilerOptions = program . getCompilerOptions ( ) ;
499520 const preferTypeOnlyImport = compilerOptions . importsNotUsedAsValues === ImportsNotUsedAsValues . Error && isValidTypeOnlyAliasUseSite ( symbolToken ) ;
500- const useRequire = shouldUseRequire ( sourceFile , compilerOptions ) ;
521+ const useRequire = shouldUseRequire ( sourceFile , program ) ;
501522 const exportInfos = getExportInfos ( symbolName , getMeaningFromLocation ( symbolToken ) , cancellationToken , sourceFile , program , useAutoImportProvider , host ) ;
502523 const fixes = arrayFrom ( flatMapIterator ( exportInfos . entries ( ) , ( [ _ , exportInfos ] ) =>
503524 getFixForImport ( exportInfos , symbolName , symbolToken . getStart ( sourceFile ) , preferTypeOnlyImport , useRequire , program , sourceFile , host , preferences ) ) ) ;
0 commit comments