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

How do we install package name maps? Window contexts #1

Closed
domenic opened this issue Mar 15, 2018 · 13 comments
Closed

How do we install package name maps? Window contexts #1

domenic opened this issue Mar 15, 2018 · 13 comments

Comments

@domenic
Copy link
Collaborator

domenic commented Mar 15, 2018

As noted in "Installing a package name map", we're not set on the idea of <script type="packagemap">, and we don't know yet exactly what to do for workers (#2).

The advantage of <script> is that it allows you to embed arbitrary data (like JSON) inline in your document. Since this is critical-path information that will be necessary before you can really get started on your module graph, that's definitely something we want to encourage. Or, is HTTP/2 push good enough for this case?

Another alternative is the <link> + Link: header. This doesn't allow embedding, but the browser can start downloading before it even sees the response body (when using the header). And it works fairly naturally for workers as well (see #2).

Any other interesting alternatives?

@domenic domenic changed the title How do we install package name maps? Window and worker contexts How do we install package name maps? Window contexts Mar 15, 2018
@bmeck
Copy link

bmeck commented Mar 15, 2018

I would like to state a minor preference towards <link>+link:. While inlining is possible you can use HTTP/2 and interleaving to get similar byte over wire behavior. The main points of why I prefer this are:

  • can send a 304 back while updating the package name map on the entry point, letting content that is not blocked on import to render without reparsing the document.
  • <script> to my knowledge always has some level of evaluation associated with it, I'm not sure this map behavior is similar.
  • discovery, services such as CDNs could define their package name map in a link: and it could be picked up by tooling and inlined into the scope mechanism (or it could be used in place of the scope mechanism)
  • I have concerns about human maintenance beyond small demo sites. Even small module graphs for simple applications can contain tens of packages. Inlining all of this seems undesirable and would make your HTML have a new JSON context switch while reading it.
    • There is something to be said about reasons why people inline <script> content for first load, but once you introduce import I think having multiple resource requests makes that workflow of doing operations as the document is still being parsed less likely.

@matthewp
Copy link

What happens with the preload scanner if the packagemap is not retrieved before it finds a bare specifier?

@domenic
Copy link
Collaborator Author

domenic commented Mar 15, 2018

@bmeck thanks for the summary.

304s can be done with (src=""-using) scripts too, right? I don't understand the point about render-blocking; that's not part of the script-based proposal.

The discovery part seems actively bad; we shouldn't be encouraging services like CDNs to be misusing whatever mechanism the browser uses for some other purpose. I'd suggest such services use a separate header that is not related to whatever we do in the browser.

I agree inline package maps are not fun to read when it's a human producing the page. For such humans I'd imagine they'd use the src="" variant of script.

@matthewp in that case the preload scanner won't preload anything for the bare specifier, and you'll need to wait for the normal loading pipeline.

@bmeck
Copy link

bmeck commented Mar 15, 2018

@domenic

304s can be done with (src=""-using) scripts too, right? I don't understand the point about render-blocking; that's not part of the script-based proposal.

Yes, but the point was that I think inline content would not have this property.

The discovery part seems actively bad; we shouldn't be encouraging services like CDNs to be misusing whatever mechanism the browser uses for some other purpose. I'd suggest such services use a separate header that is not related to whatever we do in the browser.

I would like to investigate this as an alternative to the "scope" mechanism. That is part of why I brought it up. Right now 3rd party sources cannot rely on the package name map since they don't control scoping.

I agree inline package maps are not fun to read when it's a human producing the page. For such humans I'd imagine they'd use the src="" variant of script.

I think it is actively bad, not just about fun. Having the JS and CSS context switch already is something that is fairly hefty while reading through things.

Most of my points revolve around the inline content seeming a bad idea personally. Which is the crux of the points above. I could make a separate discussion about why I think "scope" is too limiting to compose currently but if inline content is so desirable that it would preempt requiring external resources it would be hard to discuss. I personally do not see great gains from inline content, but I do think it will be limiting design if we allow it without discussing what can be done if that use is removed.

@domenic
Copy link
Collaborator Author

domenic commented Mar 15, 2018

Yes, but the point was that I think inline content would not have this property.

Remember that the idea of the script solution is to give you both options. You get the advantages of both.

Right now 3rd party sources cannot rely on the package name map since they don't control scoping.

This is a desired part of the design. See https://github.com/domenic/package-name-maps#the-scope-of-package-name-maps. We don't want to give third parties control over dependency resolution; that's an XSS waiting to happen. We can take that to a separate issue, as you mention in your last paragraph.

I think it is actively bad, not just about fun.

I understand that perspective, and can see why you wouldn't choose to use the non-external script version. But I think it's pretty important to allow it, for those who don't share your opinions, or those who are not hand-editing their HTML.

Most of my points revolve around the inline content seeming a bad idea personally.

Yeah, I can see how you personally might not use the inline variant of script. But the beauty of script is that it allows the option for each site to have their own personal choices.

I do think it will be limiting design if we allow it without discussing what can be done if that use is removed.

The intent is definitely not to limit discussion. But so far link is mostly a subset of script; the only difference is you can deliver links via HTTP headers (if we define that). So right now the weighing comes down to allowing inline vs. allowing header delivery.

Given these two, for me at least allowing inline wins.

@bmeck
Copy link

bmeck commented Mar 15, 2018

Remember that the idea of the script solution is to give you both options. You get the advantages of both.

And potential disadvantages.

We don't want to give third parties control over dependency resolution; that's an XSS waiting to happen.

I would agree for things loaded outside of their origin. There are reasons to use subresource integrity here. However, if the package name map exists on a scoped level and/or is required per resource I don't think the XSS is any more sizable than how service workers can be defined cross origin. We don't allow foreign fetch in any way with the declarative design we have right now.

But the beauty of script is that it allows the option for each site to have their own personal choices.

I'd prefer to discuss the usage rather than personal preference. I'm not sure there is significant gains from inline content, but I do think there are disadvantages.

But so far link is mostly a subset of script; the only difference is you can deliver links via HTTP headers (if we define that). So right now the weighing comes down to allowing inline vs. allowing header delivery.

Header delivery is important to me in a few senses:

  • It allows me to define expectations for a resource's package name map by defining the expected package name map. I could easily find conflicts when the link: does not match the used package name map.
  • It allows potential scoping of package name maps without requiring manual scoping. I think it could effectively remove most of the uses for the "scope" mechanism.
  • It does not suffer from the multiple module problem in the same way as import.meta.scriptElement since the HTTP cache would only have 1 resource with corresponding header. I think it is a sane avenue to investigate having multiple maps. Having a "base" package name map for the document itself is interesting and somewhat corresponds (to me at least) with how base URIs work and I don't see a conflict there.

@domenic
Copy link
Collaborator Author

domenic commented Mar 15, 2018

I'm pretty strongly against having a resource define its own package name map, at least using this format. I'd suggest opening another issue if that's important to you.

Similarly, it seems like you have some separate proposal for how to do scoping. Again, another issue, although I'll say that keeping everything in one file controlled by the app developer is very important.

@medikoo
Copy link

medikoo commented Mar 19, 2018

I think in a real world apps, we will expect package names map to be automatically generated by package manager on install/update step, and for those apps (as @bmeck pointed) they will not be trivial.
It's unlikely we will want to process this map by hand (same as we do not install packages to node_modules by hand).

Therefore I think most of us will prefer to provide it via external file (link seems fine, but technically whatever works).

@matthewp
Copy link

Just because it's in an external file doesn't mean it won't be embedded. If you're using any HTML templating language embedding it will be easy.

@phistuck
Copy link

I think HTTP headers should be available for both of the cases -
Link: </package-map.json>; rel="packagemap"
Package-Map: jquery "https://code.jquery.com/jquery.module.js" lodash "https://cdn.com/modules/lodash"
(The syntax is/should be pretty similar to Content Security Policy)

@domenic
Copy link
Collaborator Author

domenic commented Jun 20, 2018

I don't think we should pack an entire resource file into a header. Or invent a new syntax to support such packing.

@phistuck
Copy link

Of course it can be abused (just like Content Security Policy or any other header), but it is meant to describe a few packages and the syntax (again, not re-inventing the wheel) is shorter for those and can be employed site-wide by the server.

Anyway, just my thoughts.

@domenic
Copy link
Collaborator Author

domenic commented Nov 2, 2018

The proposal has changed a lot. At this point I am pretty happy with <script type="importmap">, and a lot of the discussion above feels settled. So, let me close this issue.

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

No branches or pull requests

5 participants