-
Notifications
You must be signed in to change notification settings - Fork 12
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
Fallback user stories #34
Comments
AnalysisStory (D) is basically free if we solve story (C). Inside Stories (B) and (C) point to a need for a new technology which remaps import statements:
As currently envisioned, package name maps do not solve either of these, although the adjacent concepts section mentions some ideas for solving them. Story (A) requires no special effort and should work easily. |
After talking with some folks, I realized that when I say
for cases (C) and (D), what I really mean is "The code shipped to the browser should contain What developers write may in fact still be |
I should also mention that in an offline chat @guybedford was suggesting a different approach, which basically lumps together user stories (C) and (D). Basically, we'd ship bundled, non-module code to both sets of browsers. This would require some new addition to nomodule, e.g. nopackagemap. And it would cause browsers that don't implement package name maps to get the low-fidelity experience for a site for an increased amount of time, which is unfortunate. It generally makes built-in modules unusable without tools for that interim, which is especially bad. But it does make things simpler. |
Some other user stories, not sure if they are the most important, but I imagine these feature requests might come up at some point: (E) New features for a broadly supported LAPIThe web developer wants to support the following classes of web browsers:
Let's say
I'd say #53 can handle this case very well, using a path-specific mapping which is applied in the application code which directs to a wrapper module, and within that wrapper module, the mapping is not applied. (F) Load a different (non-polyfill) library version when built-in module not availableLike (B) in terms of supported browsers, but opposite in terms of factoring: Let's say Globalize.js wants to use the latest Intl features (becoming a thin wrapper instead of a huge bundle with lots of data), which we are (hypothetically) exposing via built-in module, but fall back to its old implementation when not supported. The solution to (B) is applicable if Globalize rewrites itself to be based on an Intl-shaped interface internally, but sometimes this translation is a bit impractical (e.g., say Intl actually supports many more features than Globalize, and it's difficult to separate out which ones will be called out to from the shim). About (C)--I would be more worried about this transition if there weren't already such promising polyfills that aim to bridge this particular gap. |
@littledan when trying to write up an example for your use case (E), I realized that for For use case (F), I vaguely understand it, but not well enough to write up an example. I'll try to finish my draft of WICG/import-maps#53, then maybe you can help fill in an example into the ones I'm currently working on. |
@domenic Yes, your solution to (E) sounds good to me; I guess if we went with frozen built-in modules, you'd have to use subclassing or something like that. Adding exports doesn't sound so bad, given that modules can export everything from another module, and the mapping is scoped to exclude the new version. Removing is similar, just more annoying since you have to list each thing you want to re-export. As we discussed offline, (F) can be met by top-level await. To give a concrete example, if you're currently doing feature testing like this export let formatNumber;
if (typeof Intl.NumberFormat === "undefined") {
formatNumber = /* Something using Intl.NumberFormat */
} else {
formatNumber = /* from-scratch definition */
} you could replace it to something like this, if the "next NumberFormat" comes from a built-in module: export let formatNumber;
try {
let { NumberFormat } = await import("@std/intl/number-format");
formatNumber = /* Something using NumberFormat */
} catch {
formatNumber = /* from-scratch definition */
} |
I want to write up an issue to capture some foundational issues around fallbacks which have been floating around, but not consolidated. For example #33 is trying to solve these problems, without stating them, which makes it more confusing.
For the purposes of this discussion, let's assume that the fallback technology we're going to use is some form of package name maps, and that the syntax for importing standard modules is
import "std:x"
. Neither of these assumptions are intrinsic; they're made so that we can have a more concrete discussion.(A) No fallback needed
The web developer wants to support the following classes of web browsers:
They should be able to write
import "std:async-local-storage"
and get that standard library feature.(B) Fallback for this specific LAPI
The web developer wants to support the following classes of web browsers:
The developer has hosted a polyfill for the other supported browsers at
/node_modules/als-polyfill/index.mjs
.The developer should be able to write
import "std:async-local-storage"
and:std:async-local-storage
in class (1) browsers/node_modules/als-polyfill/index.mjs
in class (2) browsers(C) Fallback for package name map support
The web developer wants to support the following classes of web browsers:
The developer has hosted a polyfill for the other supported browsers at
/node_modules/als-polyfill/index.mjs
.The developer should be able to write
import "/node_modules/als-polyfill/index.mjs"
and:std:async-local-storage
in class (1) browsers/node_modules/als-polyfill/index.mjs
in class (2) and (3) browsers.(D) Non-module browsers
In addition to the above, the web developer also wants to support browsers with no JS module support at all (i.e., non-evergreen browsers). Call these class (4) browsers.
In this case, we can assume the developer is following best practices and writing their app using the nomodule pattern:
The text was updated successfully, but these errors were encountered: