Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

module: disable cjs snapshotting into esm loader #34467

Closed
wants to merge 1 commit into from

Conversation

guybedford
Copy link
Contributor

@guybedford guybedford commented Jul 21, 2020

This disables the instant snapshotting of CJS modules into the ESM loader as soon as they are loaded, regardless of whether those modules are loaded as ESM.

This allows loaders to support named exports for CJS modules, which isn't currently possible with the loader hook module as the snapshot process bypasses the loader hooks.

Since the PR at #33416 for CommonJS named exports has stalled due to a remaining blocker, this will allow loaders to enable that use case.

This was originally implemented in order to ensure that the snapshot of the module.exports value was always a sync exact snapshot at execution completion. In addition this allows CJS modules to be more easily garbage collected since they are not by default injected into the ESM loader if not directly loaded from it.

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

@nodejs-github-bot nodejs-github-bot added the esm Issues and PRs related to the ECMAScript Modules implementation. label Jul 21, 2020
@guybedford
Copy link
Contributor Author

/cc @nodejs/modules-active-members this was as discussed at the last meeting.

@guybedford guybedford requested a review from bmeck July 21, 2020 20:46
@bmeck
Copy link
Member

bmeck commented Jul 21, 2020

The issue is that this means that every single CJS module loaded is being bound into the ESM registry and can never be garbage collected.

Isn't this true for anything that is set to an exported name, even without this PR?

@guybedford
Copy link
Contributor Author

Isn't this true for anything that is set to an exported name, even without this PR?

Yes, if they are explicitly imported into the ES module loader from the CommonJS loader. Most CommonJS modules are not though.

@bmeck
Copy link
Member

bmeck commented Jul 21, 2020

Overall if we can get an example of a named exports loader I agree with the concept of this, but might be more inclined to a different API. Removal of CommonJS values often don't GC anyway due to require.cache so I'd state that as being less compelling.

@devsnek
Copy link
Member

devsnek commented Jul 21, 2020

i'm not a fan of this. worth exploring better module gcing of course, but i think the snapshots are an important behavior we should keep.

@jkrems
Copy link
Contributor

jkrems commented Jul 21, 2020

I considered the snapshots an awkward mechanism for a while now. It seems like a leaky abstraction when the CJS system populates ESM caches. I get the theoretical appeal but I don't think it's worth the workarounds, especially when they prevent things like user-land exploration of alternate CJS loading strategies.

@guybedford
Copy link
Contributor Author

@bmeck I've updated the description to reflect the fact that this is first and foremost about allowing named exports loaders.

I'd be glad to put such a loader together for this PR, I just am watching series right now and trying to forget my life problems.

@guybedford
Copy link
Contributor Author

@bmeck as requested, here is a CJS named exports loader that will work with this PR approach - https://github.com/guybedford/cjs-named-exports-loader.

@nodejs-github-bot
Copy link
Collaborator

guybedford added a commit that referenced this pull request Jul 29, 2020
PR-URL: #34467
Reviewed-By: Bradley Farias <[email protected]>
Reviewed-By: Geoffrey Booth <[email protected]>
@guybedford
Copy link
Contributor Author

Landed in 1fe39f0.

@guybedford guybedford closed this Jul 29, 2020
@devsnek
Copy link
Member

devsnek commented Jul 30, 2020

Please revert this. I did not approve of it landing.

@bmeck
Copy link
Member

bmeck commented Jul 30, 2020

@devsnek please the the request changes feature in such a case. this was discussed at the modules WG yesterday as well as being left open with approvals. we can queue it to the modules wg again I guess.

@devsnek
Copy link
Member

devsnek commented Jul 30, 2020

I believe snapshots, because of the predictability they provide, are a useful invariant of our esm/cjs interop. I'm happy to discuss technical details of export detection and gcing and whatnot as I don't think this feature fundamentally blocks those from working.

@jasnell
Copy link
Member

jasnell commented Jul 30, 2020

Reopening this since it was reverted...

@jasnell jasnell reopened this Jul 30, 2020
Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

Marking this with a Request Changes to keep it from landing again before the issues can be worked through

@guybedford
Copy link
Contributor Author

I do want to be explicit in closing this - we either snapshot the CommonJS module.exports values on startup or we do not, and with the direct block on the very concept there's no other way around that question.

Per my comment in #34562 (review) there will be other ways to tackle the CJS GC question if anyone wants to dig into that, but that would be separate work from this.

For the named exports feature we can work around this invariant instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
esm Issues and PRs related to the ECMAScript Modules implementation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants