Skip to content

Commit 2d1fd89

Browse files
committed
Add diagnostic for explaining file's implied format if based on package.json
1 parent e37236d commit 2d1fd89

7 files changed

+52
-5
lines changed

src/compiler/diagnosticMessages.json

+12
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,18 @@
14641464
"category": "Message",
14651465
"code": 1457
14661466
},
1467+
"File is CommonJS module because '{0}' does have field \"type\" or it's value is not \"module\"": {
1468+
"category": "Message",
1469+
"code": 1458
1470+
},
1471+
"File is CommonJS module because 'package.json' was not found": {
1472+
"category": "Message",
1473+
"code": 1459
1474+
},
1475+
"File is ECMAScript module because '{0}' has field \"type\" with value \"module\"": {
1476+
"category": "Message",
1477+
"code": 1460
1478+
},
14671479

14681480
"The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": {
14691481
"category": "Error",

src/compiler/program.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3718,7 +3718,7 @@ namespace ts {
37183718
if (locationReason && fileIncludeReasons?.length === 1) fileIncludeReasons = undefined;
37193719
const location = locationReason && getReferencedFileLocation(getSourceFileByPath, locationReason);
37203720
const fileIncludeReasonDetails = fileIncludeReasons && chainDiagnosticMessages(fileIncludeReasons, Diagnostics.The_file_is_in_the_program_because_Colon);
3721-
const redirectInfo = file && explainIfFileIsRedirect(file);
3721+
const redirectInfo = file && explainIfFileIsRedirectAndImpliedFormat(file);
37223722
const chain = chainDiagnosticMessages(redirectInfo ? fileIncludeReasonDetails ? [fileIncludeReasonDetails, ...redirectInfo] : redirectInfo : fileIncludeReasonDetails, diagnostic, ...args || emptyArray);
37233723
return location && isReferenceFileLocation(location) ?
37243724
createFileDiagnosticFromMessageChain(location.file, location.pos, location.end - location.pos, chain, relatedInfo) :

src/compiler/watch.ts

+35-4
Original file line numberDiff line numberDiff line change
@@ -224,26 +224,57 @@ namespace ts {
224224
for (const file of program.getSourceFiles()) {
225225
write(`${toFileName(file, relativeFileName)}`);
226226
reasons.get(file.path)?.forEach(reason => write(` ${fileIncludeReasonToDiagnostics(program, reason, relativeFileName).messageText}`));
227-
explainIfFileIsRedirect(file, relativeFileName)?.forEach(d => write(` ${d.messageText}`));
227+
explainIfFileIsRedirectAndImpliedFormat(file, relativeFileName)?.forEach(d => write(` ${d.messageText}`));
228228
}
229229
}
230230

231-
export function explainIfFileIsRedirect(file: SourceFile, fileNameConvertor?: (fileName: string) => string): DiagnosticMessageChain[] | undefined {
231+
export function explainIfFileIsRedirectAndImpliedFormat(
232+
file: SourceFile,
233+
fileNameConvertor?: (fileName: string) => string,
234+
): DiagnosticMessageChain[] | undefined {
232235
let result: DiagnosticMessageChain[] | undefined;
233236
if (file.path !== file.resolvedPath) {
234-
(result ||= []).push(chainDiagnosticMessages(
237+
(result ??= []).push(chainDiagnosticMessages(
235238
/*details*/ undefined,
236239
Diagnostics.File_is_output_of_project_reference_source_0,
237240
toFileName(file.originalFileName, fileNameConvertor)
238241
));
239242
}
240243
if (file.redirectInfo) {
241-
(result ||= []).push(chainDiagnosticMessages(
244+
(result ??= []).push(chainDiagnosticMessages(
242245
/*details*/ undefined,
243246
Diagnostics.File_redirects_to_file_0,
244247
toFileName(file.redirectInfo.redirectTarget, fileNameConvertor)
245248
));
246249
}
250+
if (isExternalOrCommonJsModule(file)) {
251+
switch (file.impliedNodeFormat) {
252+
case ModuleKind.ESNext:
253+
if (file.affectingFileLocations?.length) {
254+
(result ??= []).push(chainDiagnosticMessages(
255+
/*details*/ undefined,
256+
Diagnostics.File_is_ECMAScript_module_because_0_has_field_type_with_value_module,
257+
toFileName(file.affectingFileLocations[0], fileNameConvertor)
258+
));
259+
}
260+
break;
261+
case ModuleKind.CommonJS:
262+
if (file.affectingFileLocations?.length) {
263+
(result ??= []).push(chainDiagnosticMessages(
264+
/*details*/ undefined,
265+
Diagnostics.File_is_CommonJS_module_because_0_does_have_field_type_or_it_s_value_is_not_module,
266+
toFileName(file.affectingFileLocations[0], fileNameConvertor)
267+
));
268+
}
269+
else if (file.failedLookupLocations?.length) {
270+
(result ??= []).push(chainDiagnosticMessages(
271+
/*details*/ undefined,
272+
Diagnostics.File_is_CommonJS_module_because_package_json_was_not_found,
273+
));
274+
}
275+
break;
276+
}
277+
}
247278
return result;
248279
}
249280

tests/baselines/reference/tscWatch/moduleResolution/package-json-file-is-edited-when-package-json-with-type-module-exists.js

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ src/fileB.mts
6363
Matched by default include pattern '**/*'
6464
src/fileA.ts
6565
Matched by default include pattern '**/*'
66+
File is ECMAScript module because 'package.json' has field "type" with value "module"
6667
[12:00:29 AM] Found 0 errors. Watching for file changes.
6768

6869
DirectoryWatcher:: Added:: WatchInfo: /project/src 1 undefined Wild card directory

tests/baselines/reference/tscWatch/moduleResolution/package-json-file-is-edited.js

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ src/fileB.mts
7373
Matched by default include pattern '**/*'
7474
src/fileA.ts
7575
Matched by default include pattern '**/*'
76+
File is CommonJS module because 'package.json' does have field "type" or it's value is not "module"
7677
[12:00:29 AM] Found 1 error. Watching for file changes.
7778

7879
DirectoryWatcher:: Added:: WatchInfo: /project/src 1 undefined Wild card directory

tests/baselines/reference/tsserver/moduleResolution/package-json-file-is-edited-when-package-json-with-type-module-exists.js

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Project '/project/src/tsconfig.json' (Configured)
5454
Matched by default include pattern '**/*'
5555
fileA.ts
5656
Matched by default include pattern '**/*'
57+
File is ECMAScript module because '../package.json' has field "type" with value "module"
5758

5859
-----------------------------------------------
5960
FileWatcher:: Added:: WatchInfo: /project/package.json 250 undefined WatchType: package.json file

tests/baselines/reference/tsserver/moduleResolution/package-json-file-is-edited.js

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Project '/project/src/tsconfig.json' (Configured)
5959
Matched by default include pattern '**/*'
6060
fileA.ts
6161
Matched by default include pattern '**/*'
62+
File is CommonJS module because '../package.json' does have field "type" or it's value is not "module"
6263

6364
-----------------------------------------------
6465
FileWatcher:: Added:: WatchInfo: /project/package.json 250 undefined WatchType: package.json file

0 commit comments

Comments
 (0)