Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect package.json "type" and module-format-specific file extensions in more module modes #57896

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion src/compiler/_namespaces/ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export * from "../transformers/generators";
export * from "../transformers/module/module";
export * from "../transformers/module/system";
export * from "../transformers/module/esnextAnd2015";
export * from "../transformers/module/node";
export * from "../transformers/module/impliedNodeFormatDependent";
export * from "../transformers/declarations/diagnostics";
export * from "../transformers/declarations";
export * from "../transformer";
Expand Down
100 changes: 65 additions & 35 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,10 @@
"category": "Error",
"code": 1292
},
"ESM syntax is not allowed in a CommonJS module when 'module' is set to 'preserve'.": {
"category": "Error",
"code": 1293
},

"'with' statements are not allowed in an async function block.": {
"category": "Error",
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ import {
getEmitFlags,
getEmitHelpers,
getEmitModuleKind,
getEmitModuleResolutionKind,
getEmitScriptTarget,
getExternalModuleName,
getIdentifierTypeArguments,
Expand Down Expand Up @@ -800,6 +801,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
newLine: compilerOptions.newLine,
noEmitHelpers: compilerOptions.noEmitHelpers,
module: getEmitModuleKind(compilerOptions),
moduleResolution: getEmitModuleResolutionKind(compilerOptions),
target: getEmitScriptTarget(compilerOptions),
sourceMap: compilerOptions.sourceMap,
inlineSourceMap: compilerOptions.inlineSourceMap,
Expand Down Expand Up @@ -867,6 +869,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
newLine: compilerOptions.newLine,
noEmitHelpers: true,
module: compilerOptions.module,
moduleResolution: compilerOptions.moduleResolution,
target: compilerOptions.target,
sourceMap: !forceDtsEmit && compilerOptions.declarationMap,
inlineSourceMap: compilerOptions.inlineSourceMap,
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/factory/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ import {
getAllAccessorDeclarations,
getEmitFlags,
getEmitHelpers,
getEmitModuleFormatOfFile,
getEmitModuleKind,
getESModuleInterop,
getExternalModuleName,
getExternalModuleNameFromPath,
getImpliedNodeFormatForEmit,
getJSDocType,
getJSDocTypeTag,
getModifiers,
Expand Down Expand Up @@ -712,7 +714,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node
if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) {
let namedBindings: NamedImportBindings | undefined;
const moduleKind = getEmitModuleKind(compilerOptions);
if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || sourceFile.impliedNodeFormat === ModuleKind.ESNext) {
if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || getImpliedNodeFormatForEmit(sourceFile, compilerOptions) === ModuleKind.ESNext) {
// use named imports
const helpers = getEmitHelpers(sourceFile);
if (helpers) {
Expand Down Expand Up @@ -769,10 +771,8 @@ export function getOrCreateExternalHelpersModuleNameIfNeeded(factory: NodeFactor
return externalHelpersModuleName;
}

const moduleKind = getEmitModuleKind(compilerOptions);
let create = (hasExportStarsToExportValues || (getESModuleInterop(compilerOptions) && hasImportStarOrImportDefault))
&& moduleKind !== ModuleKind.System
&& (moduleKind < ModuleKind.ES2015 || node.impliedNodeFormat === ModuleKind.CommonJS);
&& getEmitModuleFormatOfFile(node, compilerOptions) < ModuleKind.System;
if (!create) {
const helpers = getEmitHelpers(node);
if (helpers) {
Expand Down
21 changes: 14 additions & 7 deletions src/compiler/moduleSpecifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
getBaseFileName,
GetCanonicalFileName,
getConditions,
getDefaultResolutionModeForFile,
getDirectoryPath,
getEmitModuleResolutionKind,
getModeForResolutionAtIndex,
Expand Down Expand Up @@ -134,7 +135,7 @@ export interface ModuleSpecifierPreferences {
/**
* @param syntaxImpliedNodeFormat Used when the import syntax implies ESM or CJS irrespective of the mode of the file.
*/
getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: SourceFile["impliedNodeFormat"]): ModuleSpecifierEnding[];
getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: ResolutionMode): ModuleSpecifierEnding[];
}

/** @internal */
Expand All @@ -154,8 +155,10 @@ export function getModuleSpecifierPreferences(
importModuleSpecifierPreference === "project-relative" ? RelativePreference.ExternalNonRelative :
RelativePreference.Shortest,
getAllowedEndingsInPreferredOrder: syntaxImpliedNodeFormat => {
const preferredEnding = syntaxImpliedNodeFormat !== importingSourceFile.impliedNodeFormat ? getPreferredEnding(syntaxImpliedNodeFormat) : filePreferredEnding;
if ((syntaxImpliedNodeFormat ?? importingSourceFile.impliedNodeFormat) === ModuleKind.ESNext) {
const impliedNodeFormat = getDefaultResolutionModeForFile(importingSourceFile, compilerOptions);
const preferredEnding = syntaxImpliedNodeFormat !== impliedNodeFormat ? getPreferredEnding(syntaxImpliedNodeFormat) : filePreferredEnding;
const moduleResolution = getEmitModuleResolutionKind(compilerOptions);
if ((syntaxImpliedNodeFormat ?? impliedNodeFormat) === ModuleKind.ESNext && ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext) {
if (shouldAllowImportingTsExtension(compilerOptions, importingSourceFile.fileName)) {
return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.JsExtension];
}
Expand Down Expand Up @@ -195,7 +198,7 @@ export function getModuleSpecifierPreferences(
}
return getModuleSpecifierEndingPreference(
importModuleSpecifierEnding,
resolutionMode ?? importingSourceFile.impliedNodeFormat,
resolutionMode ?? getDefaultResolutionModeForFile(importingSourceFile, compilerOptions),
compilerOptions,
importingSourceFile,
);
Expand Down Expand Up @@ -266,7 +269,7 @@ function getModuleSpecifierWorker(
const info = getInfo(importingSourceFileName, host);
const modulePaths = getAllModulePaths(info, toFileName, host, userPreferences, options);
return firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode)) ||
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, options.overrideImportMode || importingSourceFile.impliedNodeFormat, preferences);
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, options.overrideImportMode || getDefaultResolutionModeForFile(importingSourceFile, compilerOptions), preferences);
}

/** @internal */
Expand Down Expand Up @@ -388,7 +391,11 @@ function computeModuleSpecifiers(
if (reason.kind !== FileIncludeKind.Import || reason.file !== importingSourceFile.path) return undefined;
// If the candidate import mode doesn't match the mode we're generating for, don't consider it
// TODO: maybe useful to keep around as an alternative option for certain contexts where the mode is overridable
if (importingSourceFile.impliedNodeFormat && importingSourceFile.impliedNodeFormat !== getModeForResolutionAtIndex(importingSourceFile, reason.index, compilerOptions)) return undefined;
const existingMode = getModeForResolutionAtIndex(importingSourceFile, reason.index, compilerOptions);
andrewbranch marked this conversation as resolved.
Show resolved Hide resolved
const targetMode = options.overrideImportMode ?? getDefaultResolutionModeForFile(importingSourceFile, compilerOptions);
if (existingMode !== targetMode && existingMode !== undefined && targetMode !== undefined) {
return undefined;
}
const specifier = getModuleNameStringLiteralAt(importingSourceFile, reason.index).text;
// If the preference is for non relative and the module specifier is relative, ignore it
return preferences.relativePreference !== RelativePreference.NonRelative || !pathIsRelative(specifier) ?
Expand Down Expand Up @@ -1078,7 +1085,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath);
if (isPackageJsonInfo(cachedPackageJson) || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) {
const packageJsonContent: Record<string, any> | undefined = cachedPackageJson?.contents.packageJsonContent || tryParseJson(host.readFile!(packageJsonPath)!);
const importMode = overrideMode || importingSourceFile.impliedNodeFormat;
const importMode = overrideMode || getDefaultResolutionModeForFile(importingSourceFile, options);
if (getResolvePackageJsonExports(options)) {
// The package name that we found in node_modules could be different from the package
// name in the package.json content via url/filepath dependency specifiers. We need to
Expand Down
Loading
Loading