GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — module: do not check circular dependencies for exported proxies by BridgeAR · Pull Request #33338 · nodejs/node

Conversation

@BridgeAR

@BridgeAR BridgeAR commented May 10, 2020

Copy link
Copy Markdown
Member

In case the exported module is a proxy that has the getPrototypeOf
or setPrototypeOf trap, skip the circular dependencies check.
It would otherwise be triggered by the check itself.

Fixes: #33334

Signed-off-by: Ruben Bridgewater [email protected]

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

bricss reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@BridgeAR
BridgeAR requested a review from addaleax May 10, 2020 11:56
richardlau
richardlau reviewed May 10, 2020
View reviewed changes
Comment thread test/fixtures/cycles/warning-skip-proxy-traps-a.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

rickyes
rickyes reviewed May 10, 2020
View reviewed changes
Comment thread lib/internal/modules/cjs/loader.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/internal/modules/cjs/loader.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@ghost

ghost commented May 10, 2020 •
edited by ghost
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

I don't really like the direction this is going. Even with these changes it still triggers some traps (get for example):

module.exports = new Proxy({}, {
  get(){
    assert.fail(); // Throws here
  }
});

But, in general, altering user's objects is really bad practice. I understand the intention is to help users resolve problems regarding circular dependencies, but it brings the cobra effect. Consider the following example:

// Script A
module.exports = someCondition ? new MyClass() : {};

// Script B
const A = require('./A');
if (Object.getPrototypeOf(A) !== Object.prototype) {
  // Here we know that `someCondition` is true
} else {
  // Here we know that `someCondition` is false
}

It does not work as expected in v14.x. May I suggest removing this entire feature, or at least adding an opt-in flag for that? Most of the users know what they are doing and altering random objects makes a lot of unexpected bugs hard to debug.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@rickyes

rickyes commented May 10, 2020 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

I don't really like the direction this is going. Even with these changes it still triggers some traps (get for example):

module.exports = new Proxy({}, {
  get(){
    assert.fail(); // Throws here
  }
});

It does not trigger the get hook to the proxy because there is no access property operation for proxy objects inside internal.

But, in general, altering user's objects is really bad practice. I understand the intention is to help users resolve problems regarding circular dependencies, but it brings the cobra effect. Consider the following example:

// Script A
module.exports = someCondition ? new MyClass() : {};

// Script B
const A = require('./A');
if (Object.getPrototypeOf(A) !== Object.prototype) {
  // Here we know that `someCondition` is true
} else {
  // Here we know that `someCondition` is false
}

Module A is proxied on loading, but the prototype will point to global.Object.prototype, so it works fine in this case.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ghost

ghost commented May 10, 2020 •
edited by ghost
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

It does not trigger the get hook to the proxy because there is no access property operation for proxy objects inside internal.

That is incorrect. It does trigger get trap. Please try it yourself before posting a comment:

// A.js
const assert = require('assert');
module.exports = new Proxy({}, {
  get(){
    assert.fail();
  }
});
require('./B');

// B.js
require('./A');

It triggers the get trap at module.exports.__esModule
(that is internal/modules/cjs/loader.js line 861).

Module A is proxied on loading, but the prototype will point to global.Object.prototype, so it works fine in this case.

That is incorrect. Please try it yourself before posting a comment:

// A.js
const someCondition = false;
class MyClass{}
module.exports = someCondition ? new MyClass() : {};
require('./B');

// B.js
const A = require('./A');
if (Object.getPrototypeOf(A) !== Object.prototype) {
  console.log('Oh, something went really bad :/');
} else {
  console.log('OK');
}
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

addaleax
addaleax approved these changes May 10, 2020
View reviewed changes

@addaleax addaleax left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM although I’m having mixed feelings, because it seems like we’re working around people’s broken Proxy implementations here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/internal/modules/cjs/loader.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/internal/modules/cjs/loader.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@addaleax

addaleax commented May 10, 2020

Copy link
Copy Markdown
Member

I don't really like the direction this is going. Even with these changes it still triggers some traps (get for example):

Yeah, I agree here – there’s no point in doing anything here for Proxy exports 👍

But, in general, altering user's objects is really bad practice.

So is exporting an incomplete Proxy from a module, I would say 🤷‍♀️

May I suggest removing this entire feature, or at least adding an opt-in flag for that?

I understand where you’re coming from, but the example code you posted is contrived, and there’s no reason to expect that it is a common occurrence, whereas this feature has enabled catching real-world bugs multiple times even before it was released. It’s making a trade-off, sure, but I would definitely disagree with the notion that it makes the overall situation worse. What’s more, it tends to improve the situation for people who are less familiar with Node.js, and those who do run into these edge cases with it can be assumed to be familiar enough with JS and Node.js to know how to work with them.

rickyes reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@BridgeAR
BridgeAR force-pushed the fix-circular-modules-check-with-proxies branch from dba07f5 to 83e5b2a Compare May 11, 2020 12:45
@BridgeAR

BridgeAR commented May 11, 2020

Copy link
Copy Markdown
Member Author

I updated the code to fully work with proxies. It will now just use the target object.

It won't "fix" the prototype example but it does seem contrived as @addaleax pointed out and I don't think we have to fix that.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@BridgeAR BridgeAR added the module Issues and PRs related to the module subsystem. label May 11, 2020
@nodejs-github-bot

nodejs-github-bot commented May 11, 2020

Copy link
Copy Markdown
Collaborator

CI: https://ci.nodejs.org/job/node-test-pull-request/31274/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

jasnell
jasnell reviewed May 11, 2020
View reviewed changes
Comment thread lib/internal/modules/cjs/loader.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@BridgeAR

This comment has been minimized.

Sign in to view
addaleax
addaleax requested changes May 11, 2020
View reviewed changes

@addaleax addaleax left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the code to fully work with proxies.

I would disagree with this – the current state of the PR seems worse than the previous version.

It will now just use the target object.

If the module.exports of a module is a Proxy, there is no point in applying this feature, because there is no way to tell how the Proxy interacts with the target object. Plus, modifying an object that is only reachable as a Proxy target breaks expectations about how Proxy objects` work in general.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@BridgeAR

BridgeAR commented May 11, 2020

Copy link
Copy Markdown
Member Author

I was already pondering if the argument about not telling how the Proxy would interact would be brought up 😄 I am fine with skipping proxies completely as well.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@BridgeAR
BridgeAR force-pushed the fix-circular-modules-check-with-proxies branch from 31b25e4 to ed49784 Compare May 11, 2020 18:12
@BridgeAR

BridgeAR commented May 11, 2020

Copy link
Copy Markdown
Member Author

Updated.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@BridgeAR
module: do not check circular dependencies for exported proxies
4e7e478
In case the exported module is a proxy that has the `getPrototypeOf`
or `setPrototypeOf` trap, skip the circular dependencies check.
It would otherwise be triggered by the check itself.

Fixes: nodejs#33334

Signed-off-by: Ruben Bridgewater <[email protected]>
@BridgeAR
BridgeAR force-pushed the fix-circular-modules-check-with-proxies branch from ed49784 to 4e7e478 Compare May 11, 2020 18:16
addaleax
addaleax approved these changes May 11, 2020
View reviewed changes
@nodejs-github-bot

nodejs-github-bot commented May 11, 2020

Copy link
Copy Markdown
Collaborator

CI: https://ci.nodejs.org/job/node-test-pull-request/31282/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

targos
targos reviewed May 11, 2020
View reviewed changes
Comment thread lib/internal/modules/cjs/loader.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

targos
targos approved these changes May 11, 2020
View reviewed changes
@BridgeAR BridgeAR added the author ready PRs with CI started, the required approvals, and no outstanding review comments. label May 11, 2020
@nodejs-github-bot

nodejs-github-bot commented May 12, 2020

Copy link
Copy Markdown
Collaborator

CI: https://ci.nodejs.org/job/node-test-pull-request/31293/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

himself65
himself65 approved these changes May 13, 2020
View reviewed changes
BridgeAR added a commit to BridgeAR/node that referenced this pull request May 14, 2020
@BridgeAR
module: do not check circular dependencies for exported proxies
24bf1ad
In case the exported module is a proxy that has the `getPrototypeOf`
or `setPrototypeOf` trap, skip the circular dependencies check.
It would otherwise be triggered by the check itself.

Fixes: nodejs#33334

Signed-off-by: Ruben Bridgewater <[email protected]>

PR-URL: nodejs#33338
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Zeyu Yang <[email protected]>
@BridgeAR

BridgeAR commented May 14, 2020

Copy link
Copy Markdown
Member Author

Landed in 24bf1ad

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@BridgeAR BridgeAR closed this May 14, 2020
codebytere pushed a commit that referenced this pull request May 16, 2020
@BridgeAR @codebytere
module: do not check circular dependencies for exported proxies
c2d2dfc
In case the exported module is a proxy that has the `getPrototypeOf`
or `setPrototypeOf` trap, skip the circular dependencies check.
It would otherwise be triggered by the check itself.

Fixes: #33334

Signed-off-by: Ruben Bridgewater <[email protected]>

PR-URL: #33338
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Zeyu Yang <[email protected]>
@codebytere codebytere mentioned this pull request May 18, 2020
v14.3.0 proposal #33452
Merged
@codebytere

codebytere commented Jun 7, 2020

Copy link
Copy Markdown
Member

@BridgeAR should this go back to 12, and if yes, could you please open a manual backport for it? There are a host of conflicts.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@codebytere codebytere added the backport-requested-v12.x label Jun 7, 2020
@addaleax addaleax added dont-land-on-v10.x and removed backport-requested-v12.x labels Jun 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@jasnell jasnell jasnell left review comments
@richardlau richardlau richardlau left review comments
@addaleax addaleax addaleax approved these changes
@himself65 himself65 himself65 approved these changes
+2 more reviewers
@rickyes rickyes rickyes left review comments
@targos targos targos approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

author ready PRs with CI started, the required approvals, and no outstanding review comments. module Issues and PRs related to the module subsystem.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Assertion error starting from v14.0.0

Uh oh!

There was an error while loading. Please reload this page.

9 participants

@BridgeAR @rickyes @addaleax @nodejs-github-bot @codebytere @jasnell @targos @richardlau @himself65
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.