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
diff options
context:
space:
mode:
authorGuy Bedford <guybedford@gmail.com>2020-09-30 14:24:34 +0300
committerGuy Bedford <guybedford@gmail.com>2020-10-01 06:46:01 +0300
commit726143e683738b0e60580bdc247e6cfa60a0783a (patch)
treedf52325923036ed0f27fb57655c953af1c687d21 /lib/internal/modules
parent4acab22ac2dd4d066c7d50eb1916e34af555eccf (diff)
module: refine module type mismatch error cases
PR-URL: https://github.com/nodejs/node/pull/35426 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'lib/internal/modules')
-rw-r--r--lib/internal/modules/cjs/loader.js24
-rw-r--r--lib/internal/modules/esm/translators.js39
2 files changed, 38 insertions, 25 deletions
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
index 6f47bbc7144..9b5752e1d26 100644
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
@@ -72,7 +72,6 @@ const fs = require('fs');
const internalFS = require('internal/fs/utils');
const path = require('path');
const { sep } = path;
-const { emitWarningSync } = require('internal/process/warning');
const { internalModuleStat } = internalBinding('fs');
const packageJsonReader = require('internal/modules/package_json_reader');
const { safeGetenv } = internalBinding('credentials');
@@ -115,6 +114,7 @@ const {
} = require('internal/util/types');
const asyncESM = require('internal/process/esm_loader');
+const { enrichCJSError } = require('internal/modules/esm/translators');
const { kEvaluated } = internalBinding('module_wrap');
const {
encodedSepRegEx,
@@ -129,28 +129,6 @@ const relativeResolveCache = ObjectCreate(null);
let requireDepth = 0;
let statCache = null;
-function enrichCJSError(err) {
- const stack = err.stack.split('\n');
-
- const lineWithErr = stack[1];
-
- /*
- The regular expression below targets the most common import statement
- usage. However, some cases are not matching, cases like import statement
- after a comment block and/or after a variable definition.
- */
- if (err.message.startsWith('Unexpected token \'export\'') ||
- (RegExpPrototypeTest(/^\s*import(?=[ {'"*])\s*(?![ (])/, lineWithErr))) {
- // Emit the warning synchronously because we are in the middle of handling
- // a SyntaxError that will throw and likely terminate the process before an
- // asynchronous warning would be emitted.
- emitWarningSync(
- 'To load an ES module, set "type": "module" in the package.json or use ' +
- 'the .mjs extension.'
- );
- }
-}
-
function stat(filename) {
filename = path.toNamespacedPath(filename);
if (statCache !== null) {
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index efbb5d92d7e..94eb275a689 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -9,9 +9,12 @@ const {
ObjectKeys,
PromisePrototypeCatch,
PromiseReject,
+ RegExpPrototypeTest,
SafeMap,
SafeSet,
StringPrototypeReplace,
+ StringPrototypeSplit,
+ StringPrototypeStartsWith,
} = primordials;
let _TYPES = null;
@@ -54,9 +57,11 @@ const experimentalImportMetaResolve =
getOptionValue('--experimental-import-meta-resolve');
const asyncESM = require('internal/process/esm_loader');
const cjsParse = require('internal/deps/cjs-module-lexer/lexer');
+const { emitWarningSync } = require('internal/process/warning');
const translators = new SafeMap();
exports.translators = translators;
+exports.enrichCJSError = enrichCJSError;
let DECODER = null;
function assertBufferSource(body, allowString, hookName) {
@@ -130,6 +135,25 @@ translators.set('module', async function moduleStrategy(url) {
return module;
});
+function enrichCJSError(err) {
+ const stack = StringPrototypeSplit(err.stack, '\n');
+ /*
+ * The regular expression below targets the most common import statement
+ * usage. However, some cases are not matching, cases like import statement
+ * after a comment block and/or after a variable definition.
+ */
+ if (StringPrototypeStartsWith(err.message, 'Unexpected token \'export\'') ||
+ RegExpPrototypeTest(/^\s*import(?=[ {'"*])\s*(?![ (])/, stack[1])) {
+ // Emit the warning synchronously because we are in the middle of handling
+ // a SyntaxError that will throw and likely terminate the process before an
+ // asynchronous warning would be emitted.
+ emitWarningSync(
+ 'To load an ES module, set "type": "module" in the package.json or use ' +
+ 'the .mjs extension.'
+ );
+ }
+}
+
// Strategy for loading a node-style CommonJS module
const isWindows = process.platform === 'win32';
const winSepRegEx = /\//g;
@@ -152,7 +176,12 @@ translators.set('commonjs', async function commonjsStrategy(url, isMain) {
exports = asyncESM.ESMLoader.cjsCache.get(module);
asyncESM.ESMLoader.cjsCache.delete(module);
} else {
- exports = CJSModule._load(filename, undefined, isMain);
+ try {
+ exports = CJSModule._load(filename, undefined, isMain);
+ } catch (err) {
+ enrichCJSError(err);
+ throw err;
+ }
}
for (const exportName of exportNames) {
@@ -190,7 +219,13 @@ function cjsPreparseModuleExports(filename) {
source = readFileSync(filename, 'utf8');
} catch {}
- const { exports, reexports } = cjsParse(source || '');
+ let exports, reexports;
+ try {
+ ({ exports, reexports } = cjsParse(source || ''));
+ } catch {
+ exports = [];
+ reexports = [];
+ }
const exportNames = new SafeSet(exports);