-
Notifications
You must be signed in to change notification settings - Fork 24
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
If we don't go with npm-style module specifiers, what should the syntax be? #20
Comments
There's also obedm503's proposal of simply not using strings. The scope would be implied in that case. |
This would then be valid: import x from temporal;
import y from 'temporal'; // an npm package, for example The difference is very subtle, and could lead to confusion/errors ... and possibly security concerns? |
Staying with strings, there aren't many options. Here are two alternatives. Not sure if either of them are "ideal", but perhaps worth mentioning: import {a} from "std(date)";
import {b} from "std(date/sub)";
import {c} from "@some/thing"; // npm
import {a} from "std|date";
import {b} from "std|date/sub";
import {c} from "@some/thing"; // npm |
i'm a fan of if we wanted to really make things distinct i'd offer up |
How about just importing from a known URL, then we could also serve those modules over standard http and instantly be backward-compatible with all current runtimes. import { Instant } from 'https://ecma-international.org/tc39/stdlib/time.js' This is how Deno does it, which means that the stdlib would also be instantly usable from Deno. Then runtimes can ship the stdlib preloaded right into the browsers if they want to... |
If the modules fetched from reserved domains are automatically cached by the browsers with a long TTL, I would agree. |
Since versioning (#17) isn't decided yet, it's hard to give an exact proposal but it should absolutely be cached. In fact, if the browsers wanted to, they could ship their own custom implementation of the stdlib that gets loaded when a load from If we are going to use SemVer, I'm suggesting that full version URLs would use
|
|
Another approach might be to use a new keyword like: import Date builtin "date" or built-in import Crypto as c |
Copied from #12 (comment) :
|
I would vote for Something that looks like an http/https URL does not make sense in all contexts you can find an |
I'm not sure I understand how |
If that's the case, then why wouldn't "the name between the |
Here's my summary:
|
None of this makes the case for why anything else is better than But all that being said, I'd like to earnestly suggest:
|
In favour if non-string syntax for among other reasons that it feels the most "standard" or as part of the "environment" and not something akin to an external import. For example assuming a host(the browser) exposes the Window import. It could be written as either of the following: import document from '@std/window'
import document from 'std:window'
import document from Window As aforementioned the first case very much conflicts negatively with npms "@Scoped packages by means of imitation(it looks like a scoped npm package, but actually isn't), i would imagine avoiding this would be in the over arching proposals best interest similar to the case with pattern matching and an overloaded The second form is, much like the first, "a magic string" that we have come to associate(implicitly/explicitly) with external packages. This form also shares some semblance to data url imports: The third conforms closer to how we already implicitly reference "standard" objects. I can't hope but wonder if this would also play well with inline modules making it easier to polyfil future/current standard library functions that are "not-yet" exposed. |
@thysultan Wouldn't the importing of bulit-in modules using identifiers actually conflict with possible future inline modules? module Window { export const x = 1 }
import { x } from Window; // lexical Window or "built-in" Window? Note that Dart uses scheme-like specifiers ( |
@zenparsing That's what makes it easier to polyfill without the need for a built-time transpiler. I was using the term polyfill in both the "imitate future features" and "fix current features/bugs" context, given there are some polyfill that only do the later. Though we might hold engine implementations to a high standard, there are times when they might be broken or are lacking in the levels of abstraction/features one might desire, introducing the need for an author to extend it to fit the bill. For example: module Window extends Window {
// extend the Window module
export const head = document.head
}
module Window {
// implement a Window polyfill
export const document = window.document
} This lays a good foundation for the consumer to never have to worry about changing import identifiers between using the builtin, or polyfill for/if any of the aforementioned reasons arise. import {head} from Window |
By thinking about backwards compatibility what about: import crypto from std`crypto` this way it could work in node like import fs from node`fs` or in require form const fs = require(nodejs`fs`)
// ... or ...
const fs = require.builtin('nodejs', 'fs') |
based off the idea of namespaces and the idea of not using strings/URL, what about? import crypto from std::crypto
// and in node .mjs
import fs from node::fs again, node/commonjs can do it's own thing be it |
|
@Mouvedia can you provide some more context? |
@obedm503 I am just saying that |
Unquoted module names are not ideal IMO:
|
@glen-84 3. seems like a deal breaker to me. |
why would you ever need to dynamically import standard modules? |
@devsnek One common case would be using a standard module from a script. |
Could the import syntax be extended to allow runtimes to use a keyword after import crypto from std "crypto";
import crypto from nodejs "crypto"; The dynamic loading syntax would be slightly more exotic: const crypto = await import(std "crypto");
const crypto = await import(nodejs "crypto"); Just thinking out aloud. |
@lazarljubenovic To be clear, there is no "invention" of a new mini-language or syntax. Imports in JS already use URLs, and the Yes, that does mean that So whether you like it or not, imports in JS already carry additional semantic information. So there are no changes or additions to the language. It's just about deciding how to use the already existing URL system. |
@Pauan no, imports in js use specifiers. Browsers have chosen (as the spec allows them to do) to treat specifiers as URLs. The difference is important - browsers aren’t the entirety of what matters. |
As Iv pointed out several times, we cannot make an educated decision if we don't clarify whether we plan to have:
Once the possibility/enablement/authorization is acknowledged—or not, we will be able to pick the right proposal for the job. Should we vote on this? Has this already been decided? Should the TC39 officially weight in on the issue? |
@ljharb Node also treats them as URLs: This was intentionally done to match with browsers, to avoid fragmenting the ecosystem. In addition, even if it was browser-specific, that's irrelevant. @lazarljubenovic 's point was that he didn't want a new syntax added to strings. And my point is that the "new" syntax (i.e. URLs) has already been added. That's still true, even if it was browser-only (which it isn't). |
Hello, I'm an outsider to this community and process who just saw Chrome's blog post. After reading through a fair bit of the issue threads about the namespace, I'm left wondering why I haven't seen any discussion of simply introducing a new global object, |
@riggs I believe polluting the global is exactly why an import-based standard library was suggested. |
Chrome shipping an experimental API is far from being a second cowpath. It's an experiment. @-prefixed namespaces for JavaScript modules has been in use for years by the platform used by something like 93% of all JavaScript users. A "cowpath" is not just "an existing implemented way to do a thing". It's the path that is beaten down by people wandering about without a particular direction or intent, who all happen to land on a given convention or pattern, and then settle on that pattern because doing things mostly the same thing as everyone else is valuable in a community. Chrome shipping an experimental API is... well, I'm not sure what the metaphorical equivalent would be, but it's about as close to the exact opposite of a cowpath that could exist. It might attract us cows, but that seems unlikely, especially in the short term. It's not something that's supported by other browsers (yet?) and since it's experimental, it's not something you can rely on anyone having, or even existing for the long term. |
@isaacs The thing that you don't seem to understand is that Microsoft mostly gave up on Chakra and switched to Blink for Edge—like Opera before. Chromium is dominant. Now check this page; out of the 21 members listed you have 10 that work for a company using webkit or blink (6 google, 2 apple, 2 microsoft) and only 3 working for Mozilla. This list isn't even up-to-date, it's probably way more now. What Google picks matters. And you will have a hard time reverting what they will eventually choose. It might even be too late… |
that page isn't anywhere near accurate, if you go to the github repo it was last updated 7 years ago. aside from that, google doesn't own tc39. please stop assuming otherwise. |
On other notes: I can't see this topic on the next TC39 agenda: |
@devsnek please don't distort what I am saying. Now here's the part which is subjective: whatever Google will pick will be the standard. |
Does a single additional global really count pollution? It handily side-steps the whole |
perhaps you're right, but either way, there is already a global to which all of the current standard library is attached: For a common From my perspective, builtin modules give us a chance to "fix" issues in the current standard. Like the new import {Base64} from core "encoding";
Base64.encode("Hello, world"); as replacements for And while new we could add new Disclaimer: There are some better and more logical arguments, this is just my take. |
Citation needed. Is npm big? Yes, definitely. 93%? Highly unlikely. And in any case, a solution requires the consensus of browsers. So if Chrome has decided on one path, then that carries a lot of weight, regardless of how big or not big npm is. |
@obedm503 I think I'm mostly curious as to why I haven't seen discussion of, e.g.: stdLib.Base64.encode("Hello, world"); Edit: Or Namespaces in the import path for stdlib stuff just seems needlessly complicated. |
Google's been doing great work in TC39, and V8 achieves a high level of spec-compliance. I'm confident that we can work towards a common conclusion here through standards. |
Having a subglobal God object hanging off of |
Yes, Google is the most dominant player in the browser market, and they swing a lot of weight, indeed quite a bit like Microsoft used to back in the day. But that's still not a cowpath, is what I'm saying. It's a highway being paved by a dominant technocrat. Which might be fine in a lot of cases, I mean, you don't want cows to run the show, and presumably the technocrats are smarter than cows about a lot of things. The idea of "paving cowpaths" in language design is that, when the goal is to design language features that will satisfy a community and be easily adopted with a minimum of disruption, it's good to take stock of the patterns that have naturally emerged. Google putting something in an experimental release is not "paving a cowpath", because in this context, Google is not the cows.
Well, "big" is subjective. I can say that more than 11 million people use npm. This number is leveling out as we reach saturation of all JavaScript developers worldwide, and is now growing merely at the rate of new JavaScript developers entering the field or switching from other languages. This is about 50% of all developers worldwide (on the order of 15-30M, depending on what you count as a "developer"). (A few years ago, it was much more of a hockey-stick.) The 93% number is based on a survey done by the JS foundation, Node.js foundation, and npm, Inc., of a worldwide sample of JavaScript (and non-JavaScript, but JavaScript-using) developers around the world, spanning an impressive number of industries. So, I don't know if that's "big", but according to the best data anyone's been able to gather, it is about 93% of all JavaScript users using npm. Of course, that doesn't mean that 93% of JS devs are publishing packages to npm. We've only got a million packages or so, in ~8M versions. But they're accessing the registry to do their JS work, so they're being exposed to the patterns of module naming conventions, and getting along fine with them. I'll leave the googling as an exercise for the reader. Start with IDC's reports on the number of devs worldwide, the JS ecosystem survey from 2018, and the great work that Laurie Voss has presented again and again, correlating the survey data to npm's internal data. Or just go find 100 JS devs, and let me know if more than 7 of them never touch npm. But this isn't about npm. This is about the namespacing pattern that people are using. npm didn't really even "invent" that so much as choose it by a process of elimination, and I don't think we've ever claimed to own it. You can use The point is that this is the cowpath, so why not pave it? Chrome is probably gonna implement the standard, because they trust TC-39 to wisely design a standard that serves the needs of JS developers, but they'll also push on it to make things move. So why not make the standard be the thing that people apparently are cool with using, and have been using for years? Why redesign this bikeshed? |
Thinking about this more, the ergonomics of using what was presented in Chrome's blog are pretty poor. Needing to rely on a special tag injected into my HTML to handle polyfills is a burden I don't currently have. If someone were to make a |
They emerged due to lack of standard namespacing mechanism, so if we were to actually introduce one, why look back at half-measures people came up with? |
This is discussed a lot in #12, but can we summarize the for/against "pave the cowpath" discussion? Pros
Cons
|
To be clear, the language doesn't need to change either way, since URLs are already used for JS imports (in both browsers and Node).
Chrome went ahead and added in One more downside of The rest seems accurate. Thanks for posting a summary of the two positions! |
Not for |
@azz Oh, well if we're talking about the new syntax proposals, then you should add a new downside: they don't work well with dynamic So really there's three proposals: |
Perhaps I'm missing something, but what is the practical use of dynamically importing a built-in module? |
@mattijs can you close the loop on this would relate to concurrent changes for stage 2? I find it a little hard to know what input would be relevant/outdated. |
The term "JavaScript" does not even exist* in the spec, how could the abbr. *: Only exception in Introduction: ECMAScript is based on several originating technologies, the most well-known being JavaScript (Netscape) and JScript (Microsoft). |
Also, as I mentioned before, I prefer something like (yes, this is slightly off topic, but it looks like they're going ahead with the |
Ideas I've heard so far:
What else are you thinking of?
Splitting into another thread based on #12 (comment) .
The text was updated successfully, but these errors were encountered: