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

Proposal: add all new core modules under a scope? (too late for http2) #389

Closed
ljharb opened this issue Oct 19, 2017 · 248 comments
Closed

Proposal: add all new core modules under a scope? (too late for http2) #389

ljharb opened this issue Oct 19, 2017 · 248 comments

Comments

@ljharb
Copy link
Member

ljharb commented Oct 19, 2017

(per https://twitter.com/MylesBorins/status/920833637351862272)

Prior to unflagging http2 in node 8, it would be worth considering if instead of adding a new core module that might break userland code; adds new complexity in determining what is a core module - something that was already done in v0.11 and v1; and requires adding a "bailout" flag to node 8 LTS.

Alternatively, if all new core modules were added under a scope, say @node/, then we'd get the following benefits:

  • no need for a new bailout flag for http2
  • never again have any conflicts with userland for new core modules
  • any "is core module" code would simply be able to add name.startsWith('@node/'), making it infinitely future-compatible
  • move from nonzero risk of breakage, to zero risk

(Whether the scope is @node or @nodejs or whatever is irrelevant; we just have to find one that's available, or where the owner is willing to give it up)

While http2 landing in node 8 and/or 9 unflagged does not block this proposal for all future core modules, we have a brief, rare window here to avoid any breakage around http2 if we do this now, prior to unflagging http2.

@Fishrock123
Copy link
Member

Fwiw I have admin access to https://www.npmjs.com/org/nodejs via Chris Dickinson.

@refack
Copy link

refack commented Oct 19, 2017

IMHO it should be considered to alias all modules with the prefixed named as well, so that new code could be uniform.

@refack
Copy link

refack commented Oct 19, 2017

RE the specific issue of the http2 conflict there's already an opt out by using require('http2/') to explicitly reference the npm package.

https://twitter.com/feross/status/920835098794082305
https://twitter.com/substack/status/920833919666106368

@ljharb
Copy link
Member Author

ljharb commented Oct 19, 2017

@refack Definitely; we'd want to alias all core modules under the namespace as well, for consistency.

Those aliases could also be added in a node 6 minor, even.

Regarding the opt-out, that's great in that it provides a mechanism for both the userland and core module to coexist - but that's not an option for published modules that will no longer be updated that depends on the userland http2.

@mcollina
Copy link
Member

I'm -1 on this for http2. But it's worth discussing as a long-term plan.

@ljharb
Copy link
Member Author

ljharb commented Oct 19, 2017

@mcollina can you elaborate on why?

@mcollina
Copy link
Member

@ljharb It has been extensively discussed before (since nodejs/http2#29), and the module has been widely publicized. require('http2') is happening in Node 9, and it will be part of the next RC.
The only question we discussed in the latest TSC meeting is how (if at all) http2 should ship in Node 8 LTS.

To note, the module maintainer is onboard with removing the flag.

@ljharb
Copy link
Member Author

ljharb commented Oct 19, 2017

None of that changes that unflagging with "http2" can still cause actual breakage, and will complicate code in anything that needs to detect core modules - including resolve, which is a transitive dependency of a very large number of modules. The module maintainer being on board in no way eliminates the breakage it could cause.

That it's been discussed before doesn't mean it's the best solution; in that entire thread, this solution wasn't brought up at all.

@mcollina
Copy link
Member

If this is about http2, then open an issue on nodejs/node and let's discuss it there on why we should revert require('http2') for the upcoming 9 release, and not ship it at all for the next 8 release.

This issue is about process than we should definitely discuss things here. We are currently derailing this conversation which is actually very interesting, but is is a major shift and we should not rush it.
BTW we shipped https://nodejs.org/api/perf_hooks.html as a new module in July, and this was not brought up.

@bmeck
Copy link
Member

bmeck commented Oct 19, 2017

I think we should also talk about reserving the prefixes of modules:

RE the specific issue of the http2 conflict there's already an opt out by using require('http2/') to explicitly reference the npm package.

Seems like we could/should reserve those prefixes. If only in ESM which has slightly different rules, that seems fine but I would like both CJS and ESM. Especially if we start having subpackages which has been brought up a couple times w/ versioning or different async implementations. Better to reserve before we need I think.

@mhdawson
Copy link
Member

On the surface it sounds like a good idea to me. Ignoring specific instances (ex http2) are there any negatives to the approach ?

@MylesBorins
Copy link
Member

@mhdawson the only negative I can think of would be the User Experience of slightly more verbose module names. That being said I feel that is appropriately offset by the various benefits

@BridgeAR
Copy link
Member

I like to idea of using scopes in general. That way everyone could also directly see if it is a userland module or not without knowing all core modules. Someone requested something in that direction, but I can not find the issue to it anymore.

@mcollina
Copy link
Member

I’m -1. It would have been fantastic if scopes were available in the beginning. However, we are left with the current state of things, were the module scope is global.

I don’t see any reason to do this unless we plan to add a lot of new modules. We don’t. The things that have been added are either part of web ecosystem (that could have been global) or are of critical importance to increase the adoption of Node (async_hooks, http2).

@ofrobots
Copy link
Contributor

Using a scope for core modules would also help address install time security issues with same named packages on npm. For example: http gets installed 129k times a month. If the login credentials of this module author were to get compromised by a rouge party then a lot of users could be affected by malicious code executed at install time.

@refack
Copy link

refack commented Oct 19, 2017

Is there a similar precedent in a different runtime?

@evanlucas
Copy link
Contributor

+1 from me. I like the idea

@bmeck
Copy link
Member

bmeck commented Oct 19, 2017

@refack In other languages? Pretty much every single one. Java packages under java.*, Rust modules under std::, etc.

@refack
Copy link

refack commented Oct 19, 2017

@refack In other languages? Pretty much every single one. Java packages under java.*, Rust modules under std::, etc.

Thanks!
Is the rust prefix exclusive? AFAIK java.* isn't nor is System.* for dotnet, i.e. userland can add classes in that namespace.

@ljharb
Copy link
Member Author

ljharb commented Oct 20, 2017

@refack to be fair, node could choose to let @node/foo, when foo is not a core module, fall back to the filesystem - which would allow for userland "core" modules - but it's probably better not to leave that open.

@ljharb
Copy link
Member Author

ljharb commented Oct 20, 2017

Although now that I think about it, that method would allow older node versions to polyfill core modules from newer node versions - so maybe that's a good idea :-)

@refack
Copy link

refack commented Oct 20, 2017

I kinda like strict separation (I'm thinking static analysis). Escape hatches could exist in a loader hook.

@ljharb
Copy link
Member Author

ljharb commented Oct 20, 2017

Aren't loader hooks for ESM, not CJS?

@bmeck
Copy link
Member

bmeck commented Oct 20, 2017

@ljharb anything going through import. Part of the reason I push hard to get people to only write import/import() going forward.

@jasnell
Copy link
Member

jasnell commented Oct 20, 2017

I've got mixed feelings on this. I can definitely understand and agree with @mcollina's point of view and my knee jerk reaction is to -1 this... but, having core modules in their own namespace does have a benefit even if at the cost of backwards consistency and usability. It would also make sense in light of the "built-in modules" concept being looked at for ESM (e.g. import * from "node:fs").

That said, given that the author of the existing http2 module has eagerly agreed to hand it over this really should not be as big of an issue as it is being made out to be.

There are a couple of things necessary here to consider:

  1. A change would need to be made to the existing loader to support the @nodejs/ scope for native modules. There's not yet a PR we can look at and I'm building the 9.0.0 binary on Sunday and we've already messaged that http2 will be included in both 9.0.0 and the 8.x LTS.

  2. On the plus side, http2 support is still Experimental and everyone who would be using it should know that, especially since we still have a nice process warning emitted when it is first used.

  3. Getting http2 into the hands of users is a much higher priority. This is obviously something users want very much.

  4. The existing userland module is unsupported, most of it's dependent modules have less than 100 downloads in the past month (if I'm being generous), and we've messaged about this consistently for well over a year now. Even the author of the the existing http2 module is looking forward to this being in core.

  5. Keep in mind that the requiring the scope for new modules would have the side effect of limiting the ability to backport those modules to LTS versions unless we also backported the loader changes necessary to support them. That's definitely not out of the question but it does raise the necessary considerations. Would we consider adding the requirement that the @nodejs/ scope is reserved for built-in modules a semver-major change? (keeping in mind the fact that npm currently allows users to associate any arbitrary scope with a private registry). It is unlikely that this would break anyone, but I would argue that it's as easily unlikely that just having require('http2') would really break anyone given the current realities of that module.

@ofrobots
Copy link
Contributor

I would propose we split the discussion of scopes in general and http2. I am +1 on scopes, but I am -1 on holding up http2 module for this.

@ljharb
Copy link
Member Author

ljharb commented Oct 20, 2017

@jasnell please note that the http2 maintainer's willingness isn't the issue, it's existing modules that depend on it that are the problem. Also note that the only part that backporting might break is reserving the scope - simply backporting a new core module with the name @nodejs/http2 would be semver-minor. It is a fair point that it'd be the same category of possible breakage as shipping "http2", but it'd only break if they used @nodejs/http2 specifically - it wouldn't break for any other names under that scope.

@ofrobots thanks, I appreciate splitting the issue - while I think it's a missed opportunity if http2 ships as-is, if it's the last unscoped core module that's added it's still better than nothing.

@apapirovski
Copy link
Member

In regards to http2, as far as I can tell, that module literally does not work in the latest v8.x. There's a fork that fixes those issues and it's required via http2.js. I feel like that's a somewhat pertinent point in all these discussions around breaking existing user-code...

@targos
Copy link
Member

targos commented Oct 21, 2017

I like the idea but I'd prefer to use a scheme like node:fs instead of a scope.

@ljharb
Copy link
Member Author

ljharb commented Oct 21, 2017

A downside of that is that things added in newer nodes couldn't be polyfilled in older ones.

Won't require('node:something') look in node_modules as well?

@mcollina
Copy link
Member

I'm not convinced, but I think this should not wait for me - if the rest of the TSC is on board with this, it could go to a vote.

@mhdawson
Copy link
Member

@nodejs/tsc can you chime in on whether you believe there is enough information/has been enough efforts on reaching a consensus that we should move to a vote?

@cjihrig
Copy link
Contributor

cjihrig commented Jul 19, 2018

+1 to a namespace, but only if done as suggested in nodejs/node#21551 (comment). I've also heard rumors that TC39 may introduce namespaces at some point. If this is the case, we should wait for that, even if it is some time out.

@ljharb
Copy link
Member Author

ljharb commented Jul 19, 2018

@cjihrig not sure where you heard any such rumors; nothing like that is anywhere close to being reality.

@mhdawson
Copy link
Member

It was mentioned that there was some discussion at the TC39 but the recommendation from that group was not to wait for it as it would be quite a while before there was anything concrete.

@cjihrig
Copy link
Contributor

cjihrig commented Jul 19, 2018

@ljharb
Copy link
Member Author

ljharb commented Jul 19, 2018

The optimism in that tweet overlooks the strong blocking objections to ever standardizing something similar from multiple committee members.

@MylesBorins
Copy link
Member

MylesBorins commented Jul 19, 2018 via email

@Trott
Copy link
Member

Trott commented Jul 31, 2018

Re-added the tsc-agenda label on behalf of @ljharb who requests:

i'd like the TSC to decide that new core modules will indeed go under a scope, so that we can begin the process of debating a specific implementation in a PR (that i'm happy to file/modify). I don't think the current PR is sufficient to create movement.

@mhdawson
Copy link
Member

mhdawson commented Aug 1, 2018

In the last TSC meeting we discussed again, there were no strong objections. What would be good is a list of modules that would move into scopes, how we are handling old apis and rules around where new modules go.

@ljharb
Copy link
Member Author

ljharb commented Aug 1, 2018

@mhdawson i think the list would either be “empty”, or “all existing core modules“ (and they wouldn’t move into scopes; they’d just also be available under the scope). New modules would go in the same place old modules go, but they’d only be requireable under the scope.

@benjamingr
Copy link
Member

I'm +1 on moving existing modules with new APIs as suggested in nodejs/node#21551 (comment) as well as moving modules like worker_threads to @nodejs/worker.

@ljharb
Copy link
Member Author

ljharb commented Aug 2, 2018

I think creating new APIs while moving existing modules is as poor idea, but that can be debated separately from moving all the current experimental core modules (and creating a place for new ones to go).

@mhdawson
Copy link
Member

mhdawson commented Aug 2, 2018

@ljharb I think the key point was that we should document a suggestion on moving/not moving (possibly in stages or in different categories like existing, experimental, new etc.) so that we can have the debate

@Trott
Copy link
Member

Trott commented Aug 21, 2018

@ljharb Since this was a proposal and it has received provisional approval, should the issue be closed and discussion moved to implementation PRs?

@ljharb
Copy link
Member Author

ljharb commented Aug 21, 2018

@Trott sure!

To reiterate: yes, all new core modules should go under a scope. I'll update nodejs/node#21551 (comment) so that it reflects an actual implementation, and we can discuss that there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests