From e13162de09c3b78141af025630153462cdfcc900 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 24 Jul 2021 17:01:42 +0200 Subject: [PATCH] module: refine `enrichCJSError` PR-URL: https://github.com/nodejs/node/pull/39507 Reviewed-By: Guy Bedford Reviewed-By: James M Snell --- lib/internal/modules/cjs/helpers.js | 2 ++ lib/internal/modules/cjs/loader.js | 2 +- lib/internal/modules/esm/translators.js | 27 ++++++++++--------------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/cjs/helpers.js index bac854e0fadbac..1e85362a9449d9 100644 --- a/lib/internal/modules/cjs/helpers.js +++ b/lib/internal/modules/cjs/helpers.js @@ -187,6 +187,7 @@ function normalizeReferrerURL(referrer) { // For error messages only - used to check if ESM syntax is in use. function hasEsmSyntax(code) { + debug('Checking for ESM syntax'); const parser = require('internal/deps/acorn/acorn/dist/acorn').Parser; let root; try { @@ -196,6 +197,7 @@ function hasEsmSyntax(code) { } return ArrayPrototypeSome(root.body, (stmt) => + stmt.type === 'ExportDefaultDeclaration' || stmt.type === 'ExportNamedDeclaration' || stmt.type === 'ImportDeclaration' || stmt.type === 'ExportAllDeclaration'); diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 31ab3a8ee9c86f..3f1dac356b81f4 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1043,7 +1043,7 @@ function wrapSafe(filename, content, cjsModuleInstance) { }); } catch (err) { if (process.mainModule === cjsModuleInstance) - enrichCJSError(err); + enrichCJSError(err, content); throw err; } } diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 6d295089e42c70..8b5d8ef3b6ab92 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -10,13 +10,11 @@ const { ObjectKeys, PromisePrototypeCatch, PromiseReject, - RegExpPrototypeTest, SafeArrayIterator, SafeMap, SafeSet, StringPrototypeReplace, StringPrototypeSlice, - StringPrototypeSplit, StringPrototypeStartsWith, SyntaxErrorPrototype, globalThis: { WebAssembly }, @@ -31,8 +29,9 @@ function lazyTypes() { const { readFileSync } = require('fs'); const { extname, isAbsolute } = require('path'); const { + hasEsmSyntax, + loadNativeModule, stripBOM, - loadNativeModule } = require('internal/modules/cjs/helpers'); const { Module: CJSModule, @@ -152,18 +151,14 @@ translators.set('module', async function moduleStrategy(url) { return module; }); -function enrichCJSError(err) { - if (err == null || ObjectGetPrototypeOf(err) !== SyntaxErrorPrototype) { - return; - } - 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])) { +/** + * @param {Error | any} err + * @param {string} [content] Content of the file, if known. + * @param {string} [filename] Useful only if `content` is unknown. + */ +function enrichCJSError(err, content, filename) { + if (err != null && ObjectGetPrototypeOf(err) === SyntaxErrorPrototype && + hasEsmSyntax(content || readFileSync(filename, 'utf-8'))) { // 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. @@ -200,7 +195,7 @@ translators.set('commonjs', async function commonjsStrategy(url, isMain) { try { exports = CJSModule._load(filename, undefined, isMain); } catch (err) { - enrichCJSError(err); + enrichCJSError(err, undefined, filename); throw err; } }