-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Built-in Modules #395
Comments
Just to gather a few constraints:
Edit: I see @bterlson already mentioned the exposing-to-the-loader constraint, apologies for the dup. |
@bterlson Thanks for starting this discussion. I think it's very important for TC39 to set some kind of precedent here since platforms (e.g. DOM) will also likely want to start putting things into their own "standard" modules. To throw another strawman out there, could we not also use a URI scheme for this purpose? import { float32x4 } SIMD from "std:SIMD"; I'm concerned about this form: import SIMD; since it would presumably have non-local effects (by adding properties to the global object). If the bindings are local instead, I would reject to it on the same grounds as |
(Updated OP with new information)
The way I see it this form is simply a shortcut for |
To clarify the polyfill scenario: I must be able to write code that can mutate, overwrite, create, or freeze, a built-in module, just like I can do right now with a built-in global. Mutation/overwriting is for when engines inevitably ship bugs, and shims want to fix them - freezing is for things like SES that want guarantees that nobody can maliciously mutate/overwrite builtin modules later - creating is to provide new modules in older environments. I also agree that whatever precedent we set should pave a cowpath for engines to add non-language-builtin builtin modules in a non-colliding way, but that ensure the same capabilities I mentioned in the previous paragraph. |
Also, the IdentifierName variant import {float32x4} from SIMD; would be future-hostile to lexical modules, FWIW. And in general, I think it's "lexically surprising" to see an identifier in that position referring to something that's not in scope.
For consistency, users need to write that as: import * as SIMD from "<whatever>"; We should try not to special-case or give special meaning to forms which import built-ins. |
Sorry, or import SIMD from "<whatever>"; if it exports an default. |
I agree with this. Of the positions so far I like a |
You can't really mutate a module or a named export you are importing, in the case of modules, it is likely to be just a shimming process via |
Exactly that, yes ^ sorry that wasn't clear. |
Another problem with the IdentifierName syntax for module specifiers is that it is hostile to existing tools that already parse |
@ljharb |
From a core language perspective, I think very little would have to be said about the semantics of supporting built-module shimming. Basically, an import of a module identified using a built-in module designator that is recognized by an implementation uses the built-in implementation unless the active module loader has explicitly registered an interest in handling that module. Unrecognized built-in modules and those that the loader has registered for over-rides are simply passed on the the loader. Loader APIs of course have to provide for registering built-in over-rides. But a simple implementation that only supports a single built-in loader doesn't need to even worry about that case. |
BTW, I also like: "std:SIMD" as long as we are confident that we can safely use "std:" without tripping over any other URI protocol. I only threw out "*SIMD" (with an escapable *) as a strawman in anticipation that there might be concerns about conflicts with things like "std:". |
@allenwb i meant, freezing it in the registry so further changes to "what gets imported" are impossible, ie, not just |
I would only hope that whatever the implementation, that consumption/publication of CJS/Node and ES6 modules can interoperate... perhaps following browserify and webpack's logic in this regard. Ir at least some awareness... |
ok, then it seems like an orthogonal issue in the design of the module loader API and really doesn't impact the idea of specifying a way to designate standard built-in modules. |
I would think that for SES purposes, the ability to lock down a builtin module from being replaced in the registry is a blocker - @erights? |
Let me try to be clearer. In the absence of a standardized or implementation provided module loader that exposes a module registry there is no way to replace (or lock down) a built-in module. So, from the perspective of the core semantics of Certainly browsers and most other significant implementation will provide such capabilities so the module loader specifications needs to address it. But it shouldn't be a blocker that forces us to avoid defining built-in modules. |
I also like the module specifier |
What about using |
Just esthetically, the leading colon looks pleasing to me. And as @nbdd0121 observes, we don't need to worry about the empty string becoming a valid scheme name. |
Of course, the obvious scheme would be "js:" or "es:".
|
Do any known file systems assign meaning to a leading ":" in file/path/device names? Over course, if we are worried about running into that, we could do "::" escaping like I suggested for "*". Regardless, I like the explicitness of intent we would get with "std:". |
Perhaps the scheme, whatever it was, could be optional for use in the case of resolving ambiguity? |
Please no - optional things cause ambiguity and would present a refactoring hazard if you suddenly added another import that made it ambiguous. Whatever format is decided, it should be always required. |
The old Mac OS uses ":" as the path name separator. Names are absolute by default, a leading ":" makes them relative, multiple leading ":" walks up the file system tree, eg, ":foo" is in the cwd, "::foo" is in the parent, etc. |
I do think this is the best one for naming URL which clear enough for human understanding |
Built-in modules come up repeatedly around the various proposals. I am making this issue to centralize the discussion such that champions of the eventual proposal have a good central location for information. I will keep this up-to-date if there is further discussion in this issue.
Existing Discussion
Syntax Options
Naming convention inside module specifier
This option entails establishing a naming convention for built-in modules. Has to be compatible with existing ecosystems, eg. we cannot clobber an npm or standard node package name.
Strawman: *-sigil
Strawman: URL scheme
Distinct syntax for built-in module imports
This option necessitates additional reflective capabilities in the Loader API to request built-in modules by name as opposed to going through the normal module resolution process.
Strawman: IdentifierName instead of StringLiteral
Semantics Requirements
Must defer to loader to resolve built-in modules (important for polyfillability). Loader may see either a special string or possibly an options record indicating that a built-in module is requested.
The text was updated successfully, but these errors were encountered: