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

Describe fallback based on top-level await #82

Merged
merged 6 commits into from Dec 11, 2018
Merged

Conversation

littledan
Copy link
Contributor

Addresses #61

@ljharb
Copy link

ljharb commented Dec 4, 2018

I’d be hesitant to include TLA in the readme - its current semantics are viral and may end up being untenable (in particular, they might make CJS support in ESM not possible, as well as having impacts in a pure ESM graph).

@littledan
Copy link
Contributor Author

littledan commented Dec 4, 2018

@ljharb @jdalton Even if you have concerns with the proposed solution, do you think the use case is realistic?

@ljharb
Copy link

ljharb commented Dec 4, 2018

All of my use cases require synchronous feature testing, method caching, and polyfilling/shimming, so I’m not sure if an await-based solution would help any of them.

@MylesBorins
Copy link
Contributor

in particular, they might make CJS support in ESM not possible

Unsure how this is the case when it is only supported in the module goal

@ljharb
Copy link

ljharb commented Dec 4, 2018

My understanding is something like this: ESM A imports CJS B which requires ESM C, and C suddenly adds TLA, which would force B to be async, which would interfere with A's import of it.

@MylesBorins
Copy link
Contributor

@ljharb there is no current plan that would have ESM being able to be required in CJS... only option right now is dynamic import which is already async... I still fail to see this limitation

@zenparsing
Copy link

zenparsing commented Dec 4, 2018

There are practical module systems (e.g. esm) that allow CJS to depend directly on ESM source modules. Top-level await will present difficulties for such systems, widening the impedance mismatch between CJS and ESM rather than narrowing it.

Regarding this PR specifically, it highlights another concern that I have about TLA. By adding an attractively dynamic alternate import form (await import(...) ) we risk confusing users about which variant to use.

@littledan
Copy link
Contributor Author

Well, I proposed another solution in #61 which does not depend on top-level await. Let's discuss the problem there.

@dcleao
Copy link

dcleao commented Dec 7, 2018

@ljharb, I think that @littledan was asking if you think that the described use case is realistic, and not if it is one of your (node?) use cases...

I feel a constant push-back on TLA, or on any form of user-land JS being able to participate in module resolution, and possibly loading. As described in the explainer, the presented reason is that switching between JS and native context is very expensive. That's surely objective, and I don't think anyone argues that that is true. However, that's not what's relevant, imo. Instead: how much slower is it compared to the alternatives that users will have to resort to to implement those use cases? Or, how worse is that compared to the impact that its absence causes on the shape of APIs?

We're flooded with valid, still current use cases. Just observe existing AMD/RequireJS applications (or SystemJS)! Definitely, these applications favor a JavaScript-centric approach to components.

Other proposed technologies, such as HTML-modules, CSS-modules and JSON-modules (let's create a spec for each file type!?) favor an HTML-centric approach to components.

I think that not having TLA or some form of loader plugin technology, it won't be possible to effectively develop JS-centric components (and probably also severely limit HTML-centric components).

Some use cases:

  • i18n loader plugin — implement a way to ("statically") import a "JSON strings" resource file corresponding to the browser's current locale; the plugin can be configured with the list of locales for which resource files exist.

  • theme loader plugin — load a different set of CSSs depending on the currently selected application theme; the plugin is configured with available theme names and corresponding CSS files/modules.

  • module configuration plugin — load the configuration (similar to out-of-band metadata) of a JS module; the effective configuration is the result of merging multiple JSON files/modules; the set of applicable files depends on the values of "global" variables of the current environment (which can change on each load; not defined at compile time (a fixed manifest, as suggested, doesn't work).

None of these would be possible to be implemented solely with client-side technologies (without dynamic, server-side endpoints).

Not everything is defined at static, compile time. The desired flexibility requires late-binding of configurations. And, we don't want that the asynchronous loading of configurations to leak asynchronicity (Promise in every return value?) to the APIs themselves.

CJS and the Node environment are not of the same nature of the Web environment. And the Web environment shouldn't become "jailed" by the nature of CJS.

I'd love to know the opinion of @guybedford on these subjects.

@littledan
Copy link
Contributor Author

This is an interesting discussion. Can we move it to the top-level await repo?

Copy link
Collaborator

@domenic domenic left a comment

Choose a reason for hiding this comment

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

LGTM with some minor nits, pushing those nits and merging

README.md Outdated

_See further discussion of this case in the issue tracker: [#61](https://github.com/domenic/package-name-maps/issues/61)._

Not all fallbacks take the role of running one piece of code. For example, sometimes, one code path is to be taken if a particular platform API exists, and another code path is taken if it doesn't exist. The import maps proposal does not aim to solve all such scenarios in a built-in way; instead, The Stage 2 TC39 proposal [top-level await](https://github.com/tc39/proposal-top-level-await) can be used to meet some of these use cases. Note that top-level await blocks import of the module containing the await.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It doesn't block import; it suspends execution like a normal await does. So I'll remove this last sentence as it seems to add confusion.

@domenic domenic merged commit 0a7ba16 into WICG:master Dec 11, 2018
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

Successfully merging this pull request may close these issues.

None yet

6 participants