@@ -504,42 +504,60 @@ namespace ts.codefix {
504504 return undefined ;
505505 }
506506
507- const indexOfNodeModules = moduleFileName . indexOf ( "node_modules" ) ;
508- if ( indexOfNodeModules < 0 ) {
507+ const indexOfTopNodeModules = moduleFileName . indexOf ( "node_modules" ) ;
508+ if ( indexOfTopNodeModules < 0 ) {
509509 return undefined ;
510510 }
511511
512- let relativeFileName : string ;
513- if ( sourceDirectory . indexOf ( moduleFileName . substring ( 0 , indexOfNodeModules - 1 ) ) === 0 ) {
514- // if node_modules folder is in this folder or any of its parent folder, no need to keep it.
515- relativeFileName = moduleFileName . substring ( indexOfNodeModules + 13 /* "node_modules\".length */ ) ;
516- }
517- else {
518- relativeFileName = getRelativePath ( moduleFileName , sourceDirectory ) ;
519- }
520-
521- relativeFileName = removeFileExtension ( relativeFileName ) ;
522- if ( endsWith ( relativeFileName , "/index" ) ) {
523- relativeFileName = getDirectoryPath ( relativeFileName ) ;
524- }
525- else {
526- try {
527- const moduleDirectory = getDirectoryPath ( moduleFileName ) ;
528- const packageJsonContent = JSON . parse ( context . host . readFile ( combinePaths ( moduleDirectory , "package.json" ) ) ) ;
512+ // Simplify the full file path to something that can be resolved by Node.
513+ // First remove the extension
514+ let moduleSpecifier = removeFileExtension ( moduleFileName ) ;
515+ // If the module could be imported by a directory name, use that directory's name
516+ moduleSpecifier = getDirectoryOrFileName ( moduleSpecifier ) ;
517+ // Get a path that's relative to node_modules or the importing file's path
518+ moduleSpecifier = getNodeResolvablePath ( moduleSpecifier ) ;
519+ // If the module was found in @types , get the actual node package name
520+ return getPackageNameFromAtTypesDirectory ( moduleSpecifier ) ;
521+
522+ function getDirectoryOrFileName ( fullModulePathWithoutExtension : string ) : string {
523+ // If the file is the main module, it can be imported by the package name
524+ const indexOfLastNodeModules = moduleFileName . lastIndexOf ( "node_modules" ) ;
525+ const indexOfSlashAtPackageRoot = moduleFileName . indexOf ( "/" , indexOfLastNodeModules + 13 /* "node_modules\".length */ ) ;
526+ const packageRootPath = moduleFileName . substring ( 0 , indexOfSlashAtPackageRoot ) ;
527+ const packageJsonPath = combinePaths ( packageRootPath , "package.json" ) ;
528+ if ( context . host . fileExists ( packageJsonPath ) ) {
529+ const packageJsonContent = JSON . parse ( context . host . readFile ( packageJsonPath ) ) ;
529530 if ( packageJsonContent ) {
530- const mainFile = packageJsonContent . main || packageJsonContent . typings ;
531- if ( mainFile ) {
532- const mainExportFile = toPath ( mainFile , moduleDirectory , getCanonicalFileName ) ;
531+ const mainFileRelative = packageJsonContent . typings || packageJsonContent . types || packageJsonContent . main ;
532+ if ( mainFileRelative ) {
533+ const mainExportFile = toPath ( mainFileRelative , packageRootPath , getCanonicalFileName ) ;
533534 if ( removeFileExtension ( mainExportFile ) === removeFileExtension ( moduleFileName ) ) {
534- relativeFileName = getDirectoryPath ( relativeFileName ) ;
535+ return packageRootPath ;
535536 }
536537 }
537538 }
538539 }
539- catch ( e ) { }
540+
541+ // If the file is index.js, it can be imported by its directory name
542+ if ( endsWith ( fullModulePathWithoutExtension , "/index" ) ) {
543+ return getDirectoryPath ( fullModulePathWithoutExtension ) ;
544+ }
545+
546+ return fullModulePathWithoutExtension ;
540547 }
541548
542- return getPackageNameFromAtTypesDirectory ( relativeFileName ) ;
549+ function getNodeResolvablePath ( path : string ) : string {
550+ const fullPathUptoNodeModules = moduleFileName . substring ( 0 , indexOfTopNodeModules - 1 ) ;
551+ if ( sourceDirectory . indexOf ( fullPathUptoNodeModules ) === 0 ) {
552+ const indexOfTopPackageName = indexOfTopNodeModules + 13 /* "node_modules\".length */ ;
553+ // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
554+ const relativeToTopNodeModules = path . substring ( indexOfTopPackageName ) ;
555+ return relativeToTopNodeModules ;
556+ }
557+ else {
558+ return getRelativePath ( path , sourceDirectory ) ;
559+ }
560+ }
543561 }
544562 }
545563
0 commit comments