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

Import maps #146

Closed
annevk opened this issue Mar 14, 2019 · 25 comments · Fixed by #454
Closed

Import maps #146

annevk opened this issue Mar 14, 2019 · 25 comments · Fixed by #454
Labels
position: positive venue: Ecma Specifications in Ecma venue: W3C CG Specifications in W3C Community Groups (e.g., WICG, Privacy CG)

Comments

@annevk
Copy link
Contributor

annevk commented Mar 14, 2019

Request for Mozilla Position on an Emerging Web Specification

This rather fundamentally impacts all fetching infrastructure and it's the way you'd polyfill lack of support for a JavaScript built-in module.

(It doesn't really feel like a primitive however as it's not necessarily available before the first fetch (e.g., one from a Link header), though perhaps if we'd delay those that could be made to work.)

@annevk annevk added venue: W3C CG Specifications in W3C Community Groups (e.g., WICG, Privacy CG) venue: Ecma Specifications in Ecma labels Mar 14, 2019
@domenic
Copy link
Contributor

domenic commented Mar 14, 2019

This rather fundamentally impacts all fetching infrastructure

I think this is a bit strong :). Here's how I see it, referencing implementation staging notes in the explainer:

  • In "stage 1", with no import: URLs or HTTPS -> HTTPS fallback supported, this only impacts the resolve a module specifier algorithm, by adding a synchronous lookup to an already-parsed in-memory structure.
  • In "stage 2", with HTTPS -> HTTPS fallback supported, this gets trickier. One path is to make resolve a module specifier async and involve calling fetch-a-single-module-script repeatedly. Still not that bad, but a definite step up in complexity.
  • In "stage 3", with import: URLs, this adds a new entry to scheme-fetch (similar to blob: URL fetching steps) which consists of first calling resolve-a-module-specifier, then calling main fetch.

I apologize for this context being spread out throughout a few documents, plus in my head. I am hoping to get a real spec for at least stage 1 over the next week or two. But hopefully this helps explain why I don't think it's as fundamental of a change as all that.

I agree with your assessment that it's not a primitive. It's mainly a way of (a) controlling "resolve a module specifier; (b) via import: URLs, adding an easy way to call that algorithm from anywhere that accepts a URL, without having to go through JavaScript first.

@littledan
Copy link

(Not a Mozillian, but @annevk suggested I comment here.)

Overall, I like the import maps proposal. I think it does a good job of meeting its stated goals, and could be a good basis future mechanisms for more detailed declarative ways to invoke polyfills (c.f. whatwg/html#4432).

Some issues with active discussion from web developers about whether the goals of import maps are sufficient for their use cases:

Some of these features might be possible to add in follow-on proposals; the concern has been raised that the ability to remap non-bare specifiers might interfere with some future options.

@dbaron
Copy link
Contributor

dbaron commented Mar 29, 2019

also cc: @bholley

@domenic
Copy link
Contributor

domenic commented Aug 8, 2019

FWIW the specification here has mostly settled, and the origin trial has concluded in Chrome. We're looking to send an intent to ship soon, and thoughts from Mozilla would be welcome.

@joeldenning
Copy link

👍 would love to hear an update on this.

@annevk
Copy link
Contributor Author

annevk commented Jan 8, 2020

Well, at the end of September the specification significantly reduced its scope and no longer relates to the standard library proposal. At this point it's effectively "syntactic sugar" that seems like it would make JavaScript modules easier to use.

My main concern is (still) that as stated in https://github.com/WICG/import-maps#supplying-out-of-band-metadata-for-each-module there's likely a more general solution that would work for all resources, not just JavaScript modules, and would also allow important things such as specifying integrity metadata or other request configuration.

@joeldenning
Copy link

I think that Firefox can comment on import maps without waiting on future spec work for subresource integrity and fetching options. Those are important, but separate specs that apply not just to modules with import map entries, but also modules that are not in the import map (url instead of specifier).

@annevk
Copy link
Contributor Author

annevk commented Jan 11, 2020

The thing is, if you have that, do you need import maps? Why are the concerns of import maps unique to JavaScript? Do they not apply to CSS as well, say?

@joeldenning
Copy link

joeldenning commented Jan 11, 2020

Your questions sort of confuse me, as they seem to be missing the main purposes of import maps that are described in the proposal. I am not the author of the proposal, but here's my answer to your questions.

do you need import maps?

Yes. A primary reason import maps exist is so that bare module specifiers work. e.g. import 'foo'. This is important for making ES modules more usable. Other reasons include multiple versions of the same module (via scopes) and "packages via trailing slashes".

Why are the concerns of import maps unique to JavaScript? Do they not apply to CSS as well, say?

Import maps are used in tandem with the import keyword, which currently only works with javascript modules. There are proposals for WASM modules, CSS modules, HTML modules, and maybe other kinds of modules, but my understanding is that those specs are currently held up on some security concerns being discussed in WICG/webcomponents#839 (comment). If eventually other kinds of modules can be loaded via import and import(), import maps would cover that too.

@arkadiuszwojcik
Copy link

Why are the concerns of import maps unique to JavaScript?

Because nowadays JavaScript scripts are complex so splited into chunks/packages and manained by 3rd parties. So we need npm to manage them, and for bare ES6 modules also import maps to have some basic resoluation logic marry all dependencies in web browser. CSS might be also complex but in practice such files are local so we have full control on its path. Even if CSS is some external dependency no one (as far I know) make it depend on some other external CSS. In other words dependency tree for CSS is way more shorter than for JavaScript so there is no need for import maps in case of CSS.

@frehner
Copy link

frehner commented Jan 28, 2020

Forgive my ignorance if I say something wrong or misunderstand anything here. But I would like to comment on this line:

The thing is, if you have that, do you need import maps?

As someone who's been using SystemJS 6 as a polyfill for import maps - yes!

I would love to go to an all-ESM frontend architecture, but one of the major blockers to doing that is that if you have multiple modules that all import a library (e.g. Vue), you currently have to provide a fully qualified URL for each import statement. E.G. the following line could potentially be found in multiple repositories, and in each repository, in multiple different files:

import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.esm.browser.js'

Now let's say that we want to update vue to 2.6.12 or something. We now have to go into n number of repos with m number of files to go update that URL.

So you have several concerns at this point:

  1. You go into each repo and each repo's files and update that URL. Create a PR for that repo. Get that repo deployed
  2. What about the timing of deploying those repos? If you only update one repo to 2.6.12, but the rest of the repos/files are still pointing to 2.6.11, users are now downloading two different versions of Vue!
  3. What if you're updating to a breaking change of Vue, e.g. Vue 3? You now have to figure out how to coordinate the deploys all at the same time, otherwise if mod1 imports a component from mod2 but mod1 is still on Vue2 is that going to break?

That's all been avoided by building/bundling with cjs, since Vue is only ever resolved once and only ever resolved to the same library for all files in a project. ESM doesn't currently have that, but for me, that is the (huge) main draw of import maps.

@frehner
Copy link

frehner commented Feb 13, 2020

An additional benefit of import maps is that they allow you to do overrides for specific modules, while allowing the other modules to run as their default.

For example, let's say in my app I have 2 modules I develop: mod1 and mod2. My import map looks like the following:

{
  "imports": {
    "mod1": "my.cdn.com/mod1.js",
    "mod2": "my.cdn.com/mod2.js"
  }
}

If I want to work on mod2, I can change the import map to be "mod2": "localhost:8000" and now all the other places that import {} from mod2 are automatically looking at my localhost instead of the CDN.

I don't have to be running mod1 locally anymore to work on mod2, and I don't have to go into mod1's code and rewrite all the different import statements to point to localhost:8000.

You can see how this gets even more attractive as you increase the number of modules that you have built into your app.

I guess, in summary, I don't think that implementing the import map spec should be placed on pause because it hasn't been figured out for CSS yet. (Which appears to be the case?)

As more and more libraries are going to be bundled to esm format (since nodejs support is now happening), it would be sad if devs were never able to actually start using them in the browser (at scale) because import maps have been paused and the dev experience is still significantly better when not using ESmodules.

@frehner
Copy link

frehner commented Feb 20, 2020

I think it's also important to note that snowpack generates an import map as well.

@dcleao
Copy link

dcleao commented Mar 5, 2020

I'm just a very interested party on this specification.

@arkadiuszwojcik

Even if CSS is some external dependency no one (as far I know) make it depend on some other external CSS. In other words dependency tree for CSS is way more shorter than for JavaScript so there is no need for import maps in case of CSS.

I don't agree with this. It's perfectly reasonable for a CSS to include, for example, a base theme which is made available from another package which you would refer to by bare name. The benefits provided by logical name referencing, including the scopes feature, for multi-version support, are equally useful for CSS.

Essentially, the whole logical name feature is useful to enable URL-free referencing of external resources, i.e., one provided by a different package which is independently developed/versioned. Relative URLs cannot be used in these cases.

In a big enough web application, any web resource can be an become external resource resources easily become external resources.

IMO, any type of web resource which is able to reference another web resource, through an URL (HTML, CSS, JS, ?), can benefit from the modularization ability provided by bare names and from the development supported by packages. The importance of this is independent of the number of nesting levels a particular type of web resource uses on average — a single "hardcoded" URL is bad enough, for me.

This is why I defend import maps belong to the fetch infrastructure (and not to JS's import). It's not only about JS, even though it's where its usefulness is more obvious and more immediately needed. I have been standing against seeing import maps as a JS-only thing (see WICG/import-maps#211 and https://discourse.wicg.io/t/proposal-fetch-maps/4259/28). Just rename the whole thing to "package maps" or alike and introduce a corresponding "package:" protocol.

Naturally, starting as a JS thing in a first phase and later adding the import: protocol (or "whatever:") is perfectly reasonable as a phased implementation plan.

I was worried and surprised to find that Mozilla hasn't settled on an opinion about a specification whose importance and impact to web development seems to be huge and undeniable — imo, so much more than many if not most things I see "flowing" on web standards' repos. If this is not the perfect spec, then, please, engage in improving it or complementing it, as soon as possible.

@annevk about the issues you mention, relating integrity et. al., please see @guybedford 's WICG/import-maps#208 and WICG/import-maps#209 proposals.

Whether or not you share my above opinions, @domenic , I'd like to show my appreciation for all of the work you've done in bringing import maps to its current shape.

@justinfagnani
Copy link

justinfagnani commented Apr 23, 2020

@annevk

At this point it's effectively "syntactic sugar" that seems like it would make JavaScript modules easier to use.

I think the proposal is much more important than "syntactic sugar".

First, the vast majority of standard JS modules published to npm simply won't load in browsers because they use import specifiers that are written for node module resolution. This is a major road block to using modules natively in browsers, since tooling is required for just about everything.

Second, named-imports deliver an important feature, which is abstracting away the concrete location of the module to be imported. This is used from the most basic use case of just importing from any other "package", to cases like mocking dependencies. The important new feature of import maps is that they allow this abstraction without transforming the source. The same file can be used with different import maps to map its dependencies to difference concrete locations. A current real-world example of this is module servers (ie, CDNs unpkg.com or system's like Google's module set server) that may serve the same module for different applications with different resolved module graphs.

Third, import maps serve as a standardization and record format for module resolution. Named imports are not going anywhere - the ecosystem will in all likelihood continue forward with web-incompatible specifiers without some alternative. And right now specifier resolution is a bit... under-specified. There's classic node-module-resolution for require() but used by most tools that support module imports. There's new node-module-resolution for native module support (similar but without path searching to be more compatible with import maps). And there's several extensions that bundlers allow. Import maps are helpful in providing a concrete target and interop point for tools.

@joeldenning
Copy link

As another reference point, deno now supports and encourages import maps for remote module loading. Deno documentation

@Starcounter-Jack
Copy link

Starcounter-Jack commented May 30, 2020

@annevk

The thing is, if you have that, do you need import maps? Why are the concerns of import maps unique to JavaScript? Do they not apply to CSS as well, say?

The delivery mechanism of CSS is known as it is a browser concept. In Ecmascript (where the module-specifier lives), the hosts and their delivery mechanisms are not known.

I.e. consider the generic Javascript library "usefulllib". Let says its source code needs foreign module "bar".

It must then import bar like this:

import { foo } from "bar"

rather than like this:

import { foo } from "gamengine@preloaded||blobs:muxer+bar"
import { foo } from "https://mysite.com/libs/bar"
import { foo } from "./node_modules/bar/index.js"`

As the source code of "usefulllib" that imports "bar" cannot and should not know about all existing and future Ecmascript hosts, it needs to outsource the module resolution. For this reason, indirections is not sugaring, but a necessity.

So the short answer is W3C CSS is scoped to the WWW domain while Ecma Ecmascript cannot assume this in its language specification.

@MylesBorins
Copy link

Hey All,

Wanted to drop by and see how folks are feeling about import-maps.

In WICG/import-maps#212 @domenic mentioned that the intention was to move the proposal to the HTML spec, but that it would require multiple implementor interest. Is this something Mozilla would want to help support?

@domenic
Copy link
Contributor

domenic commented Oct 22, 2020

Hi folks,

After a long hiatus, we are gearing up to send an Intent to Ship in Chrome sometime in the next week, or maybe two weeks. The spec has settled, with a couple of the outstanding edge cases the community discovered being fixed (WICG/import-maps#227 and WICG/import-maps#229). And, most importantly, @hiroshige-g did some heroic work in web-platform-tests/wpt#26064 using service workers to get us proper web platform test coverage that doesn't depend on Chromium's internals. (More on the state of the test suite in WICG/import-maps#170 (comment).)

There's surely more to do in the future, both in import maps and related areas; see https://github.com/WICG/import-maps#further-work and @guybedford's https://github.com/guybedford/import-maps-extensions. We'd love community and Mozilla input on which of those to prioritize, with the recognition that making sure the MVP lands smoothly will still take a good bit of time. But from Chrome's perspective, we're confident that the proposal at it stands is sufficiently future-compatible that we're not foreclosing anything, and we also believe that the overwhelming positivity from web developers is a sign we should deliver this value to them sooner rather than later.

With that said, we'd love to get an official position from Mozilla. I'm available for discussion over IRC, video chat, or similar if that would be helpful in working through any of the concerns raised so far.

@codehag
Copy link
Collaborator

codehag commented Oct 30, 2020

Overall, we support the intent of the import maps proposal and think it has value for allowing users to override sometimes complex urls into something more usable, and generally for greater flexibility. From our internal discussions, we have some concerns regarding speculative parsing and dynamic import maps (@annevk has opened an issue for this: WICG/import-maps#234). We may also have some other technical concerns (cc @moztcampbell for anything I missed).

@domenic
Copy link
Contributor

domenic commented Oct 30, 2020

Thank you @codehag! We're looking forward to addressing any such feedback as it is filed.

@jniac

This comment was marked as off-topic.

@dhh
Copy link

dhh commented Feb 17, 2023

Safari now supports import maps. Any progress on the Firefox end?

@myakura
Copy link

myakura commented Feb 17, 2023

@dhh
Copy link

dhh commented Feb 17, 2023

Oh! Thought it was still behind a flag. Well color me pleased then 🙏🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
position: positive venue: Ecma Specifications in Ecma venue: W3C CG Specifications in W3C Community Groups (e.g., WICG, Privacy CG)
Projects
None yet
Development

Successfully merging a pull request may close this issue.