Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions lib/internal/modules/esm/get_format.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,17 @@ function underNodeModules(url) {
}

let typelessPackageJsonFilesWarnedAbout;
function warnTypelessPackageJsonFile(pjsonPath, url) {
/**
* Called for a module with a package.json without a `type` field (or none at all) and ESM syntax.
* Warns about the missing `type` field so that the user can avoid the performance penalty of detection.
* @param {URL} url
*/
function warnIfTypelessPackageJsonFile(url) {
if (underNodeModules(url)) { return; }
const { pjsonPath, exists } = getPackageScopeConfig(url);
if (!exists) { return; }
typelessPackageJsonFilesWarnedAbout ??= new SafeSet();
if (!underNodeModules(url) && !typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) {
if (!typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) {
const warning = `Module type of ${url} is not specified and it doesn't parse as CommonJS.\n` +
'Reparsing as ES module because module syntax was detected. This incurs a performance overhead.\n' +
`To eliminate this warning, add "type": "module" to ${pjsonPath}.`;
Expand All @@ -173,7 +181,7 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE
const ext = extname(url);

if (ext === '.js') {
const { type: packageType, pjsonPath, exists: foundPackageJson } = getPackageScopeConfig(url);
const packageType = getPackageType(url);
if (packageType !== 'none') {
return packageType;
}
Expand All @@ -183,15 +191,13 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE
// but this gets called again from `defaultLoad`/`defaultLoadSync`.
// For ambiguous files (.js, no type field) we return undefined from `resolve` and re-run the check in `load`.
const format = detectModuleFormat(source, url);
if (format === 'module' && foundPackageJson) {
// This module has a .js extension, a package.json with no `type` field, and ESM syntax.
// Warn about the missing `type` field so that the user can avoid the performance penalty of detection.
warnTypelessPackageJsonFile(pjsonPath, url);
if (format === 'module') {
warnIfTypelessPackageJsonFile(url);
}
return format;
}
if (ext === '.ts' && getOptionValue('--strip-types')) {
const { type: packageType, pjsonPath, exists: foundPackageJson } = getPackageScopeConfig(url);
const packageType = getPackageType(url);
if (packageType !== 'none') {
return `${packageType}-typescript`;
}
Expand All @@ -206,10 +212,8 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE
const parsedSource = stripTypeScriptModuleTypes(stringifiedSource, fileURLToPath(url));
const detectedFormat = detectModuleFormat(parsedSource, url);
const format = `${detectedFormat}-typescript`;
if (format === 'module-typescript' && foundPackageJson) {
// This module has a .js extension, a package.json with no `type` field, and ESM syntax.
// Warn about the missing `type` field so that the user can avoid the performance penalty of detection.
warnTypelessPackageJsonFile(pjsonPath, url);
if (format === 'module-typescript') {
warnIfTypelessPackageJsonFile(url);
}
return format;
}
Expand Down
11 changes: 5 additions & 6 deletions lib/internal/modules/package_json_reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,11 @@ function getPackageScopeConfig(resolved) {
if (ArrayIsArray(result)) {
const { data, exists, path } = deserializePackageJSON(`${resolved}`, result);

return {
__proto__: null,
...data,
exists,
pjsonPath: path,
};
// `data` is not shared, so extend it in place instead of spreading it:
// spreading would invoke the lazy `imports` and `exports` getters.
data.exists = exists;
data.pjsonPath = path;
return data;
}

// This means that the response is a string
Expand Down
Loading