module: error for CJS .js load within type: module
PR-URL: https://github.com/nodejs/node/pull/29492 Reviewed-By: Jan Krems <jan.krems@gmail.com>
This commit is contained in:
parent
ac41959922
commit
4396bebfe1
@ -212,16 +212,17 @@ Module._debug = deprecate(debug, 'Module._debug is deprecated.', 'DEP0077');
|
|||||||
// -> a.<ext>
|
// -> a.<ext>
|
||||||
// -> a/index.<ext>
|
// -> a/index.<ext>
|
||||||
|
|
||||||
// Check if the directory is a package.json dir.
|
const packageJsonCache = new SafeMap();
|
||||||
const packageMainCache = Object.create(null);
|
|
||||||
// Explicit exports from package.json files
|
|
||||||
const packageExportsCache = new SafeMap();
|
|
||||||
|
|
||||||
function readPackageRaw(requestPath) {
|
function readPackage(requestPath) {
|
||||||
const jsonPath = path.resolve(requestPath, 'package.json');
|
const jsonPath = path.resolve(requestPath, 'package.json');
|
||||||
const json = internalModuleReadJSON(path.toNamespacedPath(jsonPath));
|
|
||||||
|
|
||||||
|
const existing = packageJsonCache.get(jsonPath);
|
||||||
|
if (existing !== undefined) return existing;
|
||||||
|
|
||||||
|
const json = internalModuleReadJSON(path.toNamespacedPath(jsonPath));
|
||||||
if (json === undefined) {
|
if (json === undefined) {
|
||||||
|
packageJsonCache.set(jsonPath, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,11 +233,13 @@ function readPackageRaw(requestPath) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(json);
|
const parsed = JSON.parse(json);
|
||||||
packageMainCache[requestPath] = parsed.main;
|
const filtered = {
|
||||||
if (experimentalExports) {
|
main: parsed.main,
|
||||||
packageExportsCache.set(requestPath, parsed.exports);
|
exports: parsed.exports,
|
||||||
}
|
type: parsed.type
|
||||||
return parsed;
|
};
|
||||||
|
packageJsonCache.set(jsonPath, filtered);
|
||||||
|
return filtered;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
e.path = jsonPath;
|
e.path = jsonPath;
|
||||||
e.message = 'Error parsing ' + jsonPath + ': ' + e.message;
|
e.message = 'Error parsing ' + jsonPath + ': ' + e.message;
|
||||||
@ -244,33 +247,33 @@ function readPackageRaw(requestPath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readPackage(requestPath) {
|
function readPackageScope(checkPath) {
|
||||||
const entry = packageMainCache[requestPath];
|
const rootSeparatorIndex = checkPath.indexOf(path.sep);
|
||||||
if (entry)
|
let separatorIndex;
|
||||||
return entry;
|
while (
|
||||||
|
(separatorIndex = checkPath.lastIndexOf(path.sep)) > rootSeparatorIndex
|
||||||
const pkg = readPackageRaw(requestPath);
|
) {
|
||||||
if (pkg === false) return false;
|
checkPath = checkPath.slice(0, separatorIndex);
|
||||||
|
if (checkPath.endsWith(path.sep + 'node_modules'))
|
||||||
return pkg.main;
|
return false;
|
||||||
|
const pjson = readPackage(checkPath);
|
||||||
|
if (pjson) return pjson;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function readExports(requestPath) {
|
function readPackageMain(requestPath) {
|
||||||
if (packageExportsCache.has(requestPath)) {
|
const pkg = readPackage(requestPath);
|
||||||
return packageExportsCache.get(requestPath);
|
return pkg ? pkg.main : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pkg = readPackageRaw(requestPath);
|
function readPackageExports(requestPath) {
|
||||||
if (!pkg) {
|
const pkg = readPackage(requestPath);
|
||||||
packageExportsCache.set(requestPath, null);
|
return pkg ? pkg.exports : undefined;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkg.exports;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryPackage(requestPath, exts, isMain, originalPath) {
|
function tryPackage(requestPath, exts, isMain, originalPath) {
|
||||||
const pkg = readPackage(requestPath);
|
const pkg = readPackageMain(requestPath);
|
||||||
|
|
||||||
if (!pkg) {
|
if (!pkg) {
|
||||||
return tryExtensions(path.resolve(requestPath, 'index'), exts, isMain);
|
return tryExtensions(path.resolve(requestPath, 'index'), exts, isMain);
|
||||||
@ -371,7 +374,7 @@ function resolveExports(nmPath, request, absoluteRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const basePath = path.resolve(nmPath, name);
|
const basePath = path.resolve(nmPath, name);
|
||||||
const pkgExports = readExports(basePath);
|
const pkgExports = readPackageExports(basePath);
|
||||||
const mappingKey = `.${expansion}`;
|
const mappingKey = `.${expansion}`;
|
||||||
|
|
||||||
if (typeof pkgExports === 'object' && pkgExports !== null) {
|
if (typeof pkgExports === 'object' && pkgExports !== null) {
|
||||||
@ -947,6 +950,12 @@ Module.prototype._compile = function(content, filename) {
|
|||||||
|
|
||||||
// Native extension for .js
|
// Native extension for .js
|
||||||
Module._extensions['.js'] = function(module, filename) {
|
Module._extensions['.js'] = function(module, filename) {
|
||||||
|
if (filename.endsWith('.js')) {
|
||||||
|
const pkg = readPackageScope(filename);
|
||||||
|
if (pkg && pkg.type === 'module') {
|
||||||
|
throw new ERR_REQUIRE_ESM(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
const content = fs.readFileSync(filename, 'utf8');
|
const content = fs.readFileSync(filename, 'utf8');
|
||||||
module._compile(content, filename);
|
module._compile(content, filename);
|
||||||
};
|
};
|
||||||
|
@ -875,7 +875,8 @@ static void InternalModuleReadJSON(const FunctionCallbackInfo<Value>& args) {
|
|||||||
const size_t size = offset - start;
|
const size_t size = offset - start;
|
||||||
if (size == 0 || (
|
if (size == 0 || (
|
||||||
size == SearchString(&chars[start], size, "\"main\"") &&
|
size == SearchString(&chars[start], size, "\"main\"") &&
|
||||||
size == SearchString(&chars[start], size, "\"exports\""))) {
|
size == SearchString(&chars[start], size, "\"exports\"") &&
|
||||||
|
size == SearchString(&chars[start], size, "\"type\""))) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Local<String> chars_string =
|
Local<String> chars_string =
|
||||||
|
@ -23,6 +23,13 @@ expect('', packageWithoutTypeMain, 'package-without-type');
|
|||||||
expect('--input-type=module', packageTypeModuleMain,
|
expect('--input-type=module', packageTypeModuleMain,
|
||||||
'ERR_INPUT_TYPE_NOT_ALLOWED', true);
|
'ERR_INPUT_TYPE_NOT_ALLOWED', true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
require('../fixtures/es-modules/package-type-module/index.js');
|
||||||
|
assert.fail('Expected CJS to fail loading from type: module package.');
|
||||||
|
} catch (e) {
|
||||||
|
assert(e.toString().match(/Error \[ERR_REQUIRE_ESM\]: Must use import to load ES Module:/));
|
||||||
|
}
|
||||||
|
|
||||||
function expect(opt = '', inputFile, want, wantsError = false) {
|
function expect(opt = '', inputFile, want, wantsError = false) {
|
||||||
// TODO: Remove when --experimental-modules is unflagged
|
// TODO: Remove when --experimental-modules is unflagged
|
||||||
opt = `--experimental-modules ${opt}`;
|
opt = `--experimental-modules ${opt}`;
|
||||||
|
@ -212,6 +212,10 @@ test({
|
|||||||
shouldFail: false,
|
shouldFail: false,
|
||||||
entry: parentFilepath,
|
entry: parentFilepath,
|
||||||
resources: {
|
resources: {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
match: true,
|
||||||
|
},
|
||||||
[parentURL]: {
|
[parentURL]: {
|
||||||
body: parentBody,
|
body: parentBody,
|
||||||
match: true,
|
match: true,
|
||||||
@ -227,6 +231,10 @@ test({
|
|||||||
preload: [depFilepath],
|
preload: [depFilepath],
|
||||||
entry: parentFilepath,
|
entry: parentFilepath,
|
||||||
resources: {
|
resources: {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
match: true,
|
||||||
|
},
|
||||||
[parentURL]: {
|
[parentURL]: {
|
||||||
body: parentBody,
|
body: parentBody,
|
||||||
match: true,
|
match: true,
|
||||||
@ -279,6 +287,10 @@ test({
|
|||||||
shouldFail: false,
|
shouldFail: false,
|
||||||
entry: depFilepath,
|
entry: depFilepath,
|
||||||
resources: {
|
resources: {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
match: true,
|
||||||
|
},
|
||||||
[depURL]: {
|
[depURL]: {
|
||||||
body: depBody,
|
body: depBody,
|
||||||
match: true,
|
match: true,
|
||||||
@ -289,6 +301,10 @@ test({
|
|||||||
shouldFail: false,
|
shouldFail: false,
|
||||||
entry: depFilepath,
|
entry: depFilepath,
|
||||||
resources: {
|
resources: {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
match: true,
|
||||||
|
},
|
||||||
[policyToDepRelativeURLString]: {
|
[policyToDepRelativeURLString]: {
|
||||||
body: depBody,
|
body: depBody,
|
||||||
match: true,
|
match: true,
|
||||||
@ -309,6 +325,10 @@ test({
|
|||||||
shouldFail: false,
|
shouldFail: false,
|
||||||
entry: depFilepath,
|
entry: depFilepath,
|
||||||
resources: {
|
resources: {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
match: true,
|
||||||
|
},
|
||||||
[policyToDepRelativeURLString]: {
|
[policyToDepRelativeURLString]: {
|
||||||
body: depBody,
|
body: depBody,
|
||||||
match: true,
|
match: true,
|
||||||
@ -351,6 +371,10 @@ test({
|
|||||||
shouldFail: false,
|
shouldFail: false,
|
||||||
entry: workerSpawningFilepath,
|
entry: workerSpawningFilepath,
|
||||||
resources: {
|
resources: {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
match: true,
|
||||||
|
},
|
||||||
[workerSpawningURL]: {
|
[workerSpawningURL]: {
|
||||||
body: workerSpawningBody,
|
body: workerSpawningBody,
|
||||||
match: true,
|
match: true,
|
||||||
@ -370,6 +394,10 @@ test({
|
|||||||
entry: workerSpawningFilepath,
|
entry: workerSpawningFilepath,
|
||||||
preload: [parentFilepath],
|
preload: [parentFilepath],
|
||||||
resources: {
|
resources: {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
match: true,
|
||||||
|
},
|
||||||
[workerSpawningURL]: {
|
[workerSpawningURL]: {
|
||||||
body: workerSpawningBody,
|
body: workerSpawningBody,
|
||||||
match: true,
|
match: true,
|
||||||
|
@ -36,8 +36,16 @@ if (!tmpdirURL.pathname.endsWith('/')) {
|
|||||||
tmpdirURL.pathname += '/';
|
tmpdirURL.pathname += '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const packageFilepath = path.join(tmpdir.path, 'package.json');
|
||||||
|
const packageURL = pathToFileURL(packageFilepath);
|
||||||
|
const packageBody = '{"main": "dep.js"}';
|
||||||
|
|
||||||
function test({ shouldFail, integrity }) {
|
function test({ shouldFail, integrity }) {
|
||||||
const resources = {
|
const resources = {
|
||||||
|
[packageURL]: {
|
||||||
|
body: packageBody,
|
||||||
|
integrity: `sha256-${hash('sha256', packageBody)}`
|
||||||
|
},
|
||||||
[depURL]: {
|
[depURL]: {
|
||||||
body: depBody,
|
body: depBody,
|
||||||
integrity
|
integrity
|
||||||
|
Loading…
x
Reference in New Issue
Block a user