module: clarify CJS global-like variables not defined error message
Fixes: https://github.com/nodejs/node/issues/33741 PR-URL: https://github.com/nodejs/node/pull/37852 Reviewed-By: Guy Bedford <guybedford@gmail.com>
This commit is contained in:
parent
e7391967c2
commit
7b2bad4005
@ -4,18 +4,21 @@ const {
|
|||||||
ArrayPrototypeJoin,
|
ArrayPrototypeJoin,
|
||||||
ArrayPrototypeMap,
|
ArrayPrototypeMap,
|
||||||
ArrayPrototypePush,
|
ArrayPrototypePush,
|
||||||
|
ArrayPrototypeSome,
|
||||||
FunctionPrototype,
|
FunctionPrototype,
|
||||||
ObjectSetPrototypeOf,
|
ObjectSetPrototypeOf,
|
||||||
PromiseAll,
|
PromiseAll,
|
||||||
PromiseResolve,
|
PromiseResolve,
|
||||||
PromisePrototypeCatch,
|
PromisePrototypeCatch,
|
||||||
ReflectApply,
|
ReflectApply,
|
||||||
|
RegExpPrototypeTest,
|
||||||
SafeArrayIterator,
|
SafeArrayIterator,
|
||||||
SafeSet,
|
SafeSet,
|
||||||
StringPrototypeIncludes,
|
StringPrototypeIncludes,
|
||||||
StringPrototypeMatch,
|
StringPrototypeMatch,
|
||||||
StringPrototypeReplace,
|
StringPrototypeReplace,
|
||||||
StringPrototypeSplit,
|
StringPrototypeSplit,
|
||||||
|
StringPrototypeStartsWith,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
|
||||||
const { ModuleWrap } = internalBinding('module_wrap');
|
const { ModuleWrap } = internalBinding('module_wrap');
|
||||||
@ -28,6 +31,19 @@ const noop = FunctionPrototype;
|
|||||||
|
|
||||||
let hasPausedEntry = false;
|
let hasPausedEntry = false;
|
||||||
|
|
||||||
|
const CJSGlobalLike = [
|
||||||
|
'require',
|
||||||
|
'module',
|
||||||
|
'exports',
|
||||||
|
'__filename',
|
||||||
|
'__dirname',
|
||||||
|
];
|
||||||
|
const isCommonJSGlobalLikeNotDefinedError = (errorMessage) =>
|
||||||
|
ArrayPrototypeSome(
|
||||||
|
CJSGlobalLike,
|
||||||
|
(globalLike) => errorMessage === `${globalLike} is not defined`
|
||||||
|
);
|
||||||
|
|
||||||
/* A ModuleJob tracks the loading of a single Module, and the ModuleJobs of
|
/* A ModuleJob tracks the loading of a single Module, and the ModuleJobs of
|
||||||
* its dependencies, over time. */
|
* its dependencies, over time. */
|
||||||
class ModuleJob {
|
class ModuleJob {
|
||||||
@ -155,7 +171,32 @@ class ModuleJob {
|
|||||||
await this.instantiate();
|
await this.instantiate();
|
||||||
const timeout = -1;
|
const timeout = -1;
|
||||||
const breakOnSigint = false;
|
const breakOnSigint = false;
|
||||||
await this.module.evaluate(timeout, breakOnSigint);
|
try {
|
||||||
|
await this.module.evaluate(timeout, breakOnSigint);
|
||||||
|
} catch (e) {
|
||||||
|
if (e?.name === 'ReferenceError' &&
|
||||||
|
isCommonJSGlobalLikeNotDefinedError(e.message)) {
|
||||||
|
e.message += ' in ES module scope';
|
||||||
|
|
||||||
|
if (StringPrototypeStartsWith(e.message, 'require ')) {
|
||||||
|
e.message += ', you can use import instead';
|
||||||
|
}
|
||||||
|
|
||||||
|
const packageConfig =
|
||||||
|
StringPrototypeStartsWith(this.module.url, 'file://') &&
|
||||||
|
RegExpPrototypeTest(/\.js(\?[^#]*)?(#.*)?$/, this.module.url) &&
|
||||||
|
require('internal/modules/esm/resolve')
|
||||||
|
.getPackageScopeConfig(this.module.url);
|
||||||
|
if (packageConfig.type === 'module') {
|
||||||
|
e.message +=
|
||||||
|
'\nThis file is being treated as an ES module because it has a ' +
|
||||||
|
`'.js' file extension and '${packageConfig.pjsonPath}' contains ` +
|
||||||
|
'"type": "module". To treat it as a CommonJS script, rename it ' +
|
||||||
|
'to use the \'.cjs\' file extension.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
return { module: this.module };
|
return { module: this.module };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -893,6 +893,7 @@ module.exports = {
|
|||||||
DEFAULT_CONDITIONS,
|
DEFAULT_CONDITIONS,
|
||||||
defaultResolve,
|
defaultResolve,
|
||||||
encodedSepRegEx,
|
encodedSepRegEx,
|
||||||
|
getPackageScopeConfig,
|
||||||
getPackageType,
|
getPackageType,
|
||||||
packageExportsResolve,
|
packageExportsResolve,
|
||||||
packageImportsResolve
|
packageImportsResolve
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
'use strict';
|
||||||
|
const common = require('../common');
|
||||||
|
const fixtures = require('../common/fixtures');
|
||||||
|
const assert = require('assert');
|
||||||
|
const { pathToFileURL } = require('url');
|
||||||
|
|
||||||
|
assert.rejects(
|
||||||
|
import('data:text/javascript,require;'),
|
||||||
|
/require is not defined in ES module scope, you can use import instead$/
|
||||||
|
).then(common.mustCall());
|
||||||
|
assert.rejects(
|
||||||
|
import('data:text/javascript,exports={};'),
|
||||||
|
/exports is not defined in ES module scope$/
|
||||||
|
).then(common.mustCall());
|
||||||
|
|
||||||
|
assert.rejects(
|
||||||
|
import('data:text/javascript,require_custom;'),
|
||||||
|
/^(?!in ES module scope)(?!use import instead).*$/
|
||||||
|
).then(common.mustCall());
|
||||||
|
|
||||||
|
const pkgUrl = pathToFileURL(fixtures.path('/es-modules/package-type-module/'));
|
||||||
|
assert.rejects(
|
||||||
|
import(new URL('./cjs.js', pkgUrl)),
|
||||||
|
/use the '\.cjs' file extension/
|
||||||
|
).then(common.mustCall());
|
||||||
|
assert.rejects(
|
||||||
|
import(new URL('./cjs.js#target', pkgUrl)),
|
||||||
|
/use the '\.cjs' file extension/
|
||||||
|
).then(common.mustCall());
|
||||||
|
assert.rejects(
|
||||||
|
import(new URL('./cjs.js?foo=bar', pkgUrl)),
|
||||||
|
/use the '\.cjs' file extension/
|
||||||
|
).then(common.mustCall());
|
||||||
|
assert.rejects(
|
||||||
|
import(new URL('./cjs.js?foo=bar#target', pkgUrl)),
|
||||||
|
/use the '\.cjs' file extension/
|
||||||
|
).then(common.mustCall());
|
||||||
|
|
||||||
|
assert.rejects(
|
||||||
|
import('data:text/javascript,require;//.js'),
|
||||||
|
/^(?!use the '\.cjs' file extension).*$/
|
||||||
|
).then(common.mustCall());
|
Loading…
x
Reference in New Issue
Block a user