Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBradley Farias <bradley.meck@gmail.com>2022-03-15 03:59:32 +0300
committerGitHub <noreply@github.com>2022-03-15 03:59:32 +0300
commita01302b8dfaa9aa6290cd6bee552c4ce30dca34c (patch)
tree1f4e9a42a536e2670a1494176869f2f34743f0e4 /lib
parent6f8c983f904ad6508f03e074524f40b2975c8cf6 (diff)
esm: make extension-less errors in type:module actionable
PR-URL: https://github.com/nodejs/node/pull/42301 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/internal/errors.js10
-rw-r--r--lib/internal/modules/esm/get_format.js22
-rw-r--r--lib/internal/modules/esm/resolve.js8
3 files changed, 29 insertions, 11 deletions
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index c0834aab9c0..dce159b94cc 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -1594,9 +1594,13 @@ E('ERR_UNHANDLED_ERROR',
E('ERR_UNKNOWN_BUILTIN_MODULE', 'No such built-in module: %s', Error);
E('ERR_UNKNOWN_CREDENTIAL', '%s identifier does not exist: %s', Error);
E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError);
-E('ERR_UNKNOWN_FILE_EXTENSION',
- 'Unknown file extension "%s" for %s',
- TypeError);
+E('ERR_UNKNOWN_FILE_EXTENSION', (ext, path, suggestion) => {
+ let msg = `Unknown file extension "${ext}" for ${path}`;
+ if (suggestion) {
+ msg += `. ${suggestion}`;
+ }
+ return msg;
+}, TypeError);
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s for URL %s',
RangeError);
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js
index 91f3c9edeb1..950a769227c 100644
--- a/lib/internal/modules/esm/get_format.js
+++ b/lib/internal/modules/esm/get_format.js
@@ -6,8 +6,9 @@ const {
ObjectPrototypeHasOwnProperty,
PromisePrototypeThen,
PromiseResolve,
+ StringPrototypeSlice,
} = primordials;
-const { extname } = require('path');
+const { basename, extname, relative } = require('path');
const { getOptionValue } = require('internal/options');
const { fetchModule } = require('internal/modules/esm/fetch_module');
const {
@@ -20,7 +21,7 @@ const experimentalNetworkImports =
getOptionValue('--experimental-network-imports');
const experimentalSpecifierResolution =
getOptionValue('--experimental-specifier-resolution');
-const { getPackageType } = require('internal/modules/esm/resolve');
+const { getPackageType, getPackageScopeConfig } = require('internal/modules/esm/resolve');
const { URL, fileURLToPath } = require('internal/url');
const { ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes;
@@ -52,7 +53,8 @@ function getDataProtocolModuleFormat(parsed) {
* @returns {string}
*/
function getFileProtocolModuleFormat(url, context, ignoreErrors) {
- const ext = extname(url.pathname);
+ const filepath = fileURLToPath(url);
+ const ext = extname(filepath);
if (ext === '.js') {
return getPackageType(url) === 'module' ? 'module' : 'commonjs';
}
@@ -63,7 +65,19 @@ function getFileProtocolModuleFormat(url, context, ignoreErrors) {
if (experimentalSpecifierResolution !== 'node') {
// Explicit undefined return indicates load hook should rerun format check
if (ignoreErrors) return undefined;
- throw new ERR_UNKNOWN_FILE_EXTENSION(ext, fileURLToPath(url));
+ let suggestion = '';
+ if (getPackageType(url) === 'module' && ext === '') {
+ const config = getPackageScopeConfig(url);
+ const fileBasename = basename(filepath);
+ const relativePath = StringPrototypeSlice(relative(config.pjsonPath, filepath), 1);
+ suggestion = 'Loading extensionless files is not supported inside of ' +
+ '"type":"module" package.json contexts. The package.json file ' +
+ `${config.pjsonPath} caused this "type":"module" context. Try ` +
+ `changing ${filepath} to have a file extension. Note the "bin" ` +
+ 'field of package.json can point to a file with an extension, for example ' +
+ `{"type":"module","bin":{"${fileBasename}":"${relativePath}.js"}}`;
+ }
+ throw new ERR_UNKNOWN_FILE_EXTENSION(ext, filepath, suggestion);
}
return getLegacyExtensionFormat(ext) ?? null;
diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js
index 5e00b53a65f..59d3bc1723e 100644
--- a/lib/internal/modules/esm/resolve.js
+++ b/lib/internal/modules/esm/resolve.js
@@ -80,10 +80,10 @@ const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS);
* @typedef {'module' | 'commonjs'} PackageType
* @typedef {{
* pjsonPath: string,
- * exports?: ExportConfig;
- * name?: string;
- * main?: string;
- * type?: PackageType;
+ * exports?: ExportConfig,
+ * name?: string,
+ * main?: string,
+ * type?: PackageType,
* }} PackageConfig
*/