diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b84d894ed1b..83aec037e85 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1156,9 +1156,11 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ name: "moduleFormatDetection", type: new Map(Object.entries({ none: ModuleFormatDetectionKind.None, + bundler: ModuleFormatDetectionKind.Bundler, node16: ModuleFormatDetectionKind.Node16, nodenext: ModuleFormatDetectionKind.NodeNext, })), + affectsModuleResolution: true, category: Diagnostics.Modules, description: Diagnostics.Specify_how_files_are_determined_to_be_ECMAScript_modules_or_CommonJS_modules, defaultValueDescription: Diagnostics.node16_when_module_is_node16_nodenext_when_module_is_nodenext_none_otherwise, diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 04fc89a37d0..591230ba0c1 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -128,6 +128,7 @@ import { getLineStarts, getMatchedFileSpec, getMatchedIncludeSpec, + getModuleFormatDetectionKind, getNewLineCharacter, getNormalizedAbsolutePath, getNormalizedAbsolutePathWithoutRoot, @@ -225,6 +226,7 @@ import { ModifierLike, ModuleBlock, ModuleDeclaration, + ModuleFormatDetectionKind, ModuleKind, ModuleResolutionCache, ModuleResolutionHost, @@ -1326,23 +1328,28 @@ export function getImpliedNodeFormatForFileWorker( host: ModuleResolutionHost, options: CompilerOptions, ) { - switch (getEmitModuleResolutionKind(options)) { - case ModuleResolutionKind.Node16: - case ModuleResolutionKind.NodeNext: + const formatDetection = getModuleFormatDetectionKind(options); + switch (formatDetection) { + case ModuleFormatDetectionKind.Bundler: + case ModuleFormatDetectionKind.Node16: + case ModuleFormatDetectionKind.NodeNext: + const defaultFormat = formatDetection === ModuleFormatDetectionKind.Bundler ? undefined : ModuleKind.CommonJS; return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext : fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS : - fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson() : + fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson(defaultFormat) : undefined; // other extensions, like `json` or `tsbuildinfo`, are set as `undefined` here but they should never be fed through the transformer pipeline default: return undefined; } - function lookupFromPackageJson(): Partial { + function lookupFromPackageJson(defaultFormat: ResolutionMode): Partial { const state = getTemporaryModuleResolutionState(packageJsonInfoCache, host, options); const packageJsonLocations: string[] = []; state.failedLookupLocations = packageJsonLocations; state.affectingLocations = packageJsonLocations; const packageJsonScope = getPackageScopeForPath(fileName, state); - const impliedNodeFormat = packageJsonScope?.contents.packageJsonContent.type === "module" ? ModuleKind.ESNext : ModuleKind.CommonJS; + const impliedNodeFormat = packageJsonScope?.contents.packageJsonContent.type === "module" ? ModuleKind.ESNext : + packageJsonScope?.contents.packageJsonContent.type === "commonjs" ? ModuleKind.CommonJS : + defaultFormat; return { impliedNodeFormat, packageJsonLocations, packageJsonScope }; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 68ae6ad0a34..358d01e90e9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -7284,6 +7284,7 @@ export enum ModuleKind { export enum ModuleFormatDetectionKind { None = 0, + Bundler = 1, Node16 = 100, NodeNext = 199, }