Fix auto-imports inserting import in CJS files under node16/node20/nodenext#3328
Draft
Fix auto-imports inserting import in CJS files under node16/node20/nodenext#3328
import in CJS files under node16/node20/nodenext#3328Conversation
… module kinds When using module: "node16"/"node18"/"node20"/"nodenext", moduleDetection defaults to "force", which sets ExternalModuleIndicator on ALL files regardless of actual syntax. This made the file content indicators unreliable for determining CJS vs ESM, and the simple module kind comparison (GetEmitModuleKind() < ModuleKindES2015) also failed because Node module kinds have numeric values >= 100. The fix adds an early check for Node module kinds that uses GetImpliedNodeFormatForEmit(), which correctly determines the runtime module format based on file extension and package.json "type" field. Agent-Logs-Url: https://github.com/microsoft/typescript-go/sessions/9405eb29-fef7-4989-a974-aba9130e0d67 Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix auto-imports inserting import statement into CJS files
Fix auto-imports inserting Apr 2, 2026
import in CJS files under node16/node20/nodenext
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With
module: "node20"(or node16/node18/nodenext) and a tsconfig.json, auto-imports incorrectly emitimportstatements in CJS files instead ofrequire()calls.Two problems in
computeShouldUseRequire():moduleDetection: "force"(the default for Node module kinds) setsExternalModuleIndicatoron all files unconditionally, so the CJS/ESM content heuristic can't distinguish CJS files from ESM filesGetEmitModuleKind() < ModuleKindES2015returnsfalsefor Node module kinds (ModuleKindNode20 = 102) even though the file may be CJSBoth cause the function to return
false(useimport) before reachingGetImpliedNodeFormatForEmit(), which would have given the correct answer based on file extension andpackage.json"type".Fix
Add an early exit for Node module kinds that delegates directly to
GetImpliedNodeFormatForEmit():For Node module kinds, the runtime format is authoritatively determined by file extension and
package.json"type"— file content indicators are unreliable under force detection.Tests
Two new fourslash tests covering the exact scenario from the issue:
module.exportssyntax +module: "node20"+package.json"type": "commonjs"ExternalModuleIndicatoralone causes the wrong result