Skip to content

Commit 8795ee5

Browse files
aduh95MylesBorins
authored andcommitted
module: deprecate module.parent
This feature does not work when a module is imported using ECMAScript modules specification, therefore it is deprecated. Fixes: nodejs/modules#469 Backport-PR-URL: #33533 PR-URL: #32217 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Bradley Farias <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent fa51ac3 commit 8795ee5

File tree

8 files changed

+51
-9
lines changed

8 files changed

+51
-9
lines changed

doc/api/deprecations.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,6 +2707,39 @@ Type: Runtime
27072707
`Transform._transformState` will be removed in future versions where it is
27082708
no longer required due to simplification of the implementation.
27092709

2710+
<a id="DEP0144"></a>
2711+
### DEP0144: `module.parent`
2712+
<!-- YAML
2713+
changes:
2714+
- version: REPLACEME
2715+
pr-url: https://github.com/nodejs/node/pull/32217
2716+
description: Documentation-only deprecation.
2717+
-->
2718+
2719+
Type: Documentation-only
2720+
2721+
A CommonJS module can access the first module that required it using
2722+
`module.parent`. This feature is deprecated because it does not work
2723+
consistently in the presence of ECMAScript modules and because it gives an
2724+
inaccurate representation of the CommonJS module graph.
2725+
2726+
Some modules use it to check if they are the entry point of the current process.
2727+
Instead, it is recommended to compare `require.main` and `module`:
2728+
2729+
```js
2730+
if (require.main === module) {
2731+
// Code section that will run only if current file is the entry point.
2732+
}
2733+
```
2734+
2735+
When looking for the CommonJS modules that have required the current one,
2736+
`require.cache` and `module.children` can be used:
2737+
2738+
```js
2739+
const moduleParents = Object.values(require.cache)
2740+
.filter((m) => m.children.includes(module));
2741+
```
2742+
27102743
<a id="DEP0XXX"></a>
27112744
### DEP0XXX: `socket.bufferSize`
27122745
<!-- YAML

doc/api/modules.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,11 +905,17 @@ loading.
905905
### `module.parent`
906906
<!-- YAML
907907
added: v0.1.16
908+
deprecated: REPLACEME
908909
-->
909910

910-
* {module}
911+
> Stability: 0 - Deprecated: Please use [`require.main`][] and
912+
> [`module.children`][] instead.
913+
914+
* {module | null | undefined}
911915

912-
The module that first required this one.
916+
The module that first required this one, or `null` if the current module is the
917+
entry point of the current process, or `undefined` if the module was loaded by
918+
something that is not a CommonJS module (E.G.: REPL or `import`).
913919

914920
### `module.path`
915921
<!-- YAML
@@ -1133,13 +1139,15 @@ consists of the following keys:
11331139
[`createRequire()`]: #modules_module_createrequire_filename
11341140
[`module` object]: #modules_the_module_object
11351141
[`module.id`]: #modules_module_id
1142+
[`module.children`]: #modules_module_children
11361143
[`path.dirname()`]: path.html#path_path_dirname_path
11371144
[ECMAScript Modules]: esm.html
11381145
[an error]: errors.html#errors_err_require_esm
11391146
[exports shortcut]: #modules_exports_shortcut
11401147
[module resolution]: #modules_all_together
11411148
[module wrapper]: #modules_the_module_wrapper
11421149
[native addons]: addons.html
1150+
[`require.main`]: #modules_require_main
11431151
[source map include directives]: https://sourcemaps.info/spec.html#h.lmz475t4mvbx
11441152
[`--enable-source-maps`]: cli.html#cli_enable_source_maps
11451153
[`NODE_V8_COVERAGE=dir`]: cli.html#cli_node_v8_coverage_dir

lib/internal/modules/cjs/loader.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,8 @@ Module._extensions['.js'] = function(module, filename) {
12491249
const pkg = readPackageScope(filename);
12501250
// Function require shouldn't be used in ES modules.
12511251
if (pkg && pkg.data && pkg.data.type === 'module') {
1252-
const parentPath = module.parent && module.parent.filename;
1252+
const { parent } = module;
1253+
const parentPath = parent && parent.filename;
12531254
const packageJsonPath = path.resolve(pkg.path, 'package.json');
12541255
throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
12551256
}

test/common/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ if (process.argv.length === 2 &&
5959
!process.env.NODE_SKIP_FLAG_CHECK &&
6060
isMainThread &&
6161
hasCrypto &&
62-
module.parent &&
62+
require.main &&
6363
require('cluster').isMaster) {
6464
// The copyright notice is relatively big and the flags could come afterwards.
6565
const bytesToRead = 1500;
6666
const buffer = Buffer.allocUnsafe(bytesToRead);
67-
const fd = fs.openSync(module.parent.filename, 'r');
67+
const fd = fs.openSync(require.main.filename, 'r');
6868
const bytesRead = fs.readSync(fd, buffer, 0, bytesToRead);
6969
fs.closeSync(fd);
7070
const source = buffer.toString('utf8', 0, bytesRead);

test/common/require-as.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable node-core/require-common-first, node-core/required-modules */
22
'use strict';
33

4-
if (module.parent) {
4+
if (require.main !== module) {
55
const { spawnSync } = require('child_process');
66

77
function runModuleAs(filename, flags, spawnOptions, role) {

test/js-native-api/test_instance_data/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
const common = require('../../common');
55
const assert = require('assert');
66

7-
if (module.parent) {
7+
if (module !== require.main) {
88
// When required as a module, run the tests.
99
const test_instance_data =
1010
require(`./build/${common.buildType}/test_instance_data`);

test/node-api/test_instance_data/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
const common = require('../../common');
55

6-
if (module.parent) {
6+
if (module !== require.main) {
77
// When required as a module, run the tests.
88
const test_instance_data =
99
require(`./build/${common.buildType}/test_instance_data`);

test/parallel/test-cli-eval.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
'use strict';
23-
if (module.parent) {
23+
if (module !== require.main) {
2424
// Signal we've been loaded as a module.
2525
// The following console.log() is part of the test.
2626
console.log('Loaded as a module, exiting with status code 42.');

0 commit comments

Comments
 (0)