Import maps - HTTP 203

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
JAKE ARCHIBALD: Well, should we do an episode? And then we can maybe try and do some of a [BLEEP] at the end for Lucas to cut around. CREW: Yup. Rolling. We are rolling. JAKE ARCHIBALD: OK. All right, where am I? SURMA: What? What? [LAUGHING] [MUSIC PLAYING] JAKE ARCHIBALD: So we spent the last couple of episodes talking about real things. Real talk. SURMA: [LAUGHS] Let's stop that. Let's not do that. JAKE ARCHIBALD: So yeah, I thought, why not just talk about some imaginary stuff this time? I want to talk about import maps, which is a new proposal that is very much in the early messing around phase. SURMA: Right. So yeah, let's give it context. Because I've seen we have an article on this. We have had a confusion about how stable certain features are when we announce them. JAKE ARCHIBALD: Right, yes. SURMA: Where is it at? JAKE ARCHIBALD: Well, yes. SURMA: [LAUGHS] Yes. JAKE ARCHIBALD: Before we talk about what it is, I would say some of it is in Chrome Canary behind the flag, an origin trial. So you can experiment with it in production, in production with the whole origin trial thing. SURMA: But none of this is set in stone, so it could still change-- how it works, why it works. JAKE ARCHIBALD: Yep. This episode could be completely useless by the time it goes out. SURMA: So I guess it's also pretty much Chrome only then at this point? JAKE ARCHIBALD: It is, yeah. SURMA: Any other browsers have it behind the flag? JAKE ARCHIBALD: Nope, nope. SURMA: All right, it's just us. JAKE ARCHIBALD: It be Chrome only. So what is it? What is it? What is it? Actually, I'm going to answer that, because I did the slides and the script and everything. We've got module imports with your-- SURMA: It's got a library? JAKE ARCHIBALD: --module scripts. See? I used your library. SURMA: That's nice. JAKE ARCHIBALD: See? You happy? SURMA: You didn't use [INAUDIBLE] for once. JAKE ARCHIBALD: No, no, I changed it up this time. But a lot of us are more familiar to seeing something like this. SURMA: Because that's how the node import works, and most of the bundle of support that kind of specifier where you just say, just put the node package name in there, and we'll resolve the rest. JAKE ARCHIBALD: Yes. And the way this actually works in node is it will start at whatever module contains this, and it will go up through all of the directories, all the parent directories, looking for directories that have node modules alongside-- SURMA: It goes upwards and tries to find the closest node-- JAKE ARCHIBALD: No, no, it'll find them all. SURMA: Oh, really? JAKE ARCHIBALD: Yeah. SURMA: That's a twist. Cool. JAKE ARCHIBALD: It goes and finds them all, and then it will find-- SURMA: So you'll put a node modules folder in slash, like in the root of my hard drive? JAKE ARCHIBALD: I think that will work. SURMA: That's amazing. JAKE ARCHIBALD: Yeah. But then there's also the special global one for your global modules, so that goes at the end as well. SURMA: I didn't know that existed. JAKE ARCHIBALD: Well, yeah, if you do NPM install dash g, goes in your global stuff. SURMA: Yeah, you're right. I never thought about that. JAKE ARCHIBALD: Yeah. Yeah, yeah. And then it will iterate through all of those, and it will look for a directory called comlink in each of those. SURMA: And if there's multiple? JAKE ARCHIBALD: Well, so it's going through them closest-- SURMA: In order. JAKE ARCHIBALD: Yes. So when it finds comlink in one of them, it will go, right, does this have a package json? If it does, then I'm going to look in the main thing, and that's the script I'm going to load. If it doesn't have that, then I'm going to try and load index.js. If that's not any good, I'm going to try and load index.json. If that's not there, I'm going to try to load index.node. SURMA: Really? JAKE ARCHIBALD: For binary modules, yes, yes, that's how it works. And if they're not there, it then goes up the directory's-- SURMA: It makes sense. Yeah, OK. JAKE ARCHIBALD: --yeah, and off it goes. SURMA: We want that on the web. Is that what you're saying? JAKE ARCHIBALD: And that's the problem is we literally cannot do that on the web, because imagine how many requests it would have to make-- SURMA: It'd be great. JAKE ARCHIBALD: --just to find script, right? SURMA: Time to interactive, two and a half years. JAKE ARCHIBALD: Yeah. [LAUGHING] Exactly. So we needed a new system in order to bring this to the web. And that is import maps. That is what we're going to talk about. SURMA: Oh, it's a new type! JAKE ARCHIBALD: It's a new script type. SURMA: Can it also put in a file? JAKE ARCHIBALD: Yes. Yes, you can, and you shouldn't. [LAUGHING] And we'll get onto why. But this is what it looks like. You'll recognize it. SURMA: So it's literally a map that maps from the identifiers to-- oh, that's interesting. Because I remember that there is a rule for both dynamic and static imports that they have to start with slash or with a relative or absolute path. JAKE ARCHIBALD: Yes. SURMA: They're not allowed to start with like this. JAKE ARCHIBALD: Yes. Modules on the web right now have to start with a dot. I think it has to be, like, dot, dot, dot-- it's dot slash? Dot, dot, slash? SURMA: I think it's slash. Otherwise it could be-- JAKE ARCHIBALD: Or a valid URL, or slash. Right? SURMA: Right. OK. JAKE ARCHIBALD: Something like that. SURMA: OK. JAKE ARCHIBALD: And so this would let you with this. Now you would just be able to reference-- SURMA: It leaves this open for-- oh, cool. OK. JAKE ARCHIBALD: Reference comlink and-- SURMA: So there is no way that an import map identifier could clash with existing production code out there right now because of that rule? JAKE ARCHIBALD: Ah, hold on to that. But yes, as long as you've got this, one of these has to go before anything that imports anything, any impulse statement. If you have one of these later on, it will just error. You'll get an error on this script tag, and it will just be ignored. So this ideally right in the head of your document before everything else. And this is where you define where we shouldn't put them in the file. And that's why you probably shouldn't put them in a file. But yes, now this works. SURMA: Neat. JAKE ARCHIBALD: Just works. Thank you for spoiling my next slide multiple times. This just goes to show we don't rehearse this, right? Yes, I would say you can do this. It has some special MIME type, but yes, you shouldn't, because then you've got this head of line looking thing. SURMA: So will that mean that a script type import map is also deferred by default? Because modules are deferred by default. JAKE ARCHIBALD: No, this will-- I mean, it's not going to block rendering of anything, but it will be immediate fetch, and it will block subsequent script tags. SURMA: Script tags. JAKE ARCHIBALD: That are using-- SURMA: So basically, if you put it in an XML file, but put the script take high up, you should still be fine? JAKE ARCHIBALD: But it's one of those things-- SURMA: [INAUDIBLE],, but you should be fine. JAKE ARCHIBALD: But there's a reason we inline scripts, right? Because if it's a very small file, then the amount you pay for that request and response-- SURMA: Will it stay small? Will people really keep small import maps? I kind of expect them to be like [BLOWS RASPBERRY].. JAKE ARCHIBALD: That is a question. And yeah, and it would be interesting. So maybe if some of the use cases we go through here, I have been also wondering how large these might get. Because the thing we saw there is, I would say, one of the more boring use cases for it. Another interesting one-- so this is the example we had before. I can import comlink because it's in the import map. SURMA: That's the thing that usually works in node. JAKE ARCHIBALD: In node land, you would have-- yep. This works as well. SURMA: Really? JAKE ARCHIBALD: You do something like this. So there's is a special rule. If the thing ends in a slash, then you are defining a prefix for all of those. SURMA: Oh, that's really nice that they thought of that. JAKE ARCHIBALD: Yes. SURMA: Because I would have expected that I'd have to define-- JAKE ARCHIBALD: Every single one. SURMA: --like do static, analyze all the inputs I have, and define a map. This is actually really neat. But they don't have a rule that can just define the last one, and index is assumed, like, it is a node? JAKE ARCHIBALD: No. Index is not assumed. And also, things-- like in node, you can miss out the extension. SURMA: Oh, yeah. No, I mean, that wouldn't just-- JAKE ARCHIBALD: You could use import maps to work around that. But you would have to do every single file and-- SURMA: Right, because basically you have to define everything. It's like here's the thing without the extension that maps to the thing with the extension. JAKE ARCHIBALD: With the extension. Yes. So you can do that, but probably don't, unless you for some reason know of a way around it. You can do this. SURMA: Oh, so maybe I can do rewrites. JAKE ARCHIBALD: Yes. SURMA: So something that is already a valid import path, I can now say, you know what? It's actually here. JAKE ARCHIBALD: Yes, absolutely. SURMA: Oh, that's neat. JAKE ARCHIBALD: And you could say that this could just create a lot of confusing code while your scripts are doing one thing. SURMA: Oh, yeah, 100%. JAKE ARCHIBALD: But I think there's a really interesting use case with this that I'm really excited about. So here's an example import. But in production, it will most likely look more like this. SURMA: Yes, because at least it should be. Because good caching-- you need this. JAKE ARCHIBALD: You need your unique file name. So then if you change the file, you will-- watch this-- boop! There you go. Change the hash. SURMA: Oh, I set you up for this one. JAKE ARCHIBALD: I know, it's great. Yeah. SURMA: It's so good. JAKE ARCHIBALD: And then it means you've changed the file. So each of those resources can cache forever, because you changed the file when you were changing the content. But the problem with this is you've now also changed the content of the parent file. SURMA: Yes. JAKE ARCHIBALD: So you need to update the hash of that file. SURMA: Yeah, and if nothing else changed, people will download a file that is exactly the same except for the imports. JAKE ARCHIBALD: Yes. SURMA: And now with the import map, I see where you're going with this. JAKE ARCHIBALD: Yes. So even with a small module change, you end up invalidating massive tree-- SURMA: Potentially-- JAKE ARCHIBALD: --the whole lot. SURMA: --always from where you did the change to the root of your thing, at least that one branch, potentially more. JAKE ARCHIBALD: It will all invalidate. So the idea is, what if we could just do that? And then in your import map that's where the hash goes. SURMA: Oh, that's very nice. JAKE ARCHIBALD: So that means if you change foo-- we just changed foo. Watch. Boop! There you go. SURMA: And so the interesting thing is this wouldn't be possible with HTTP redirects or rewrites. Because it wouldn't hit the HTTP cache. JAKE ARCHIBALD: Exactly. SURMA: You could do it may be in a service worker, I guess? JAKE ARCHIBALD: You could do this in a service worker. You could insert all of this stuff. But it wouldn't be there for that very first request where your service worker isn't installed, whereas with imports, import maps, it is just there. SURMA: Yeah. That's a really exciting use case, actually, for this. JAKE ARCHIBALD: I think it's great. And so that means, yes, the user will obviously have to download the new foo blah, blah, blah, blah, blah, but-- SURMA: But only that. JAKE ARCHIBALD: --only that. Only that small change. SURMA: And the entire rest of the pipeline can still just rely on-- you know, has to load all the static imports before executing. So everything will just work and keep working. JAKE ARCHIBALD: So I think that's a lovely little use case. So here's a fun one. So here's a fun one. We haven't done that in a while. Although I said these script things, these import map scripts, they have to be before anything that imports anything, otherwise they're invalid. So they have to be-- SURMA: Oh, they're actually invalid. I didn't catch that. I thought that just, like, the models above it wouldn't respect them. JAKE ARCHIBALD: No, it will error and ignore. SURMA: Actually, that's probably a good idea. JAKE ARCHIBALD: Yeah. So it won't error modules. It will just error on the script elements. SURMA: You see an error that there was an-- that this is not in the correct place. JAKE ARCHIBALD: And it will ignore it. SURMA: But it will also let the other things that have invalid import statements error out. JAKE ARCHIBALD: Yes. SURMA: OK. JAKE ARCHIBALD: But you can still create them dynamically, as long as you're still creating them dynamically before any of your imports. And I think this is really cool, because you could have something like this, where it does a feature test. And it could be a new JavaScript thing, could be a new DOM thing. SURMA: Oh, that is really cool. JAKE ARCHIBALD: New JavaScript syntax. And you could say, right, now dump out one of these import maps. Instead of loading main, load main modern. SURMA: So for example, I could say do you have readable stream transforms in writable stream? If I do, I'm just going to create this redirect to a small file and just re-export the native applications. If not, load the entire polyfill thing in my code, and just import one normal module. JAKE ARCHIBALD: Yes. SURMA: And that will get the polyfill if it needs to be one, otherwise it won't be. JAKE ARCHIBALD: Exactly that. SURMA: That's really cool. JAKE ARCHIBALD: But it means you could do the same with new JavaScript syntax. So if the scope operator became a thing-- let's hope it does. It's not going to, though, is it? But let's hope it does-- it means you could do something like this, direct it to another file, which makes use of that, and therefore doesn't have to be transpired, that kind of thing. SURMA: Could be smaller. JAKE ARCHIBALD: Could be smaller, hopefully. SURMA: So why did you do this? JAKE ARCHIBALD: [LAUGHS] Do you know why I did this? SURMA: No, that's why I'm asking. [LAUGHS] JAKE ARCHIBALD: Well, come on-- we do this show and-- SURMA: Well, we do this-- [MUTTERING] JAKE ARCHIBALD: Sometimes we make believe on this show a little bit just for the chat. SURMA: No, I legit-- I guess it has to do with some sort of escaping, but I didn't-- JAKE ARCHIBALD: It is. SURMA: Because this is just a normal string. This is like the only part where you make use of the template literal packets. JAKE ARCHIBALD: Yeah, the HTML compiles it. Once it enters a script-- the end of your script is when there is angle bracket slash script, angle bracket. That's the end of your script. So without this little trick, the script would end there. And all of this would bleed into the HTML. SURMA: Oh, that's the thing. Yes. Yes. I remember now. JAKE ARCHIBALD: Yes. SURMA: Even in a string literal, you can't just have angle brackets slash script, because by the time your file gets parsed, the parser will be like, yep, script ends here. JAKE ARCHIBALD: Yeah, because this is HTML parser time rather than JavaScript parser time. So yeah, you've always got to do something to work around. SURMA: This is the first time I think I've ever seen this, like both this kind of escape, but also insert adjacent HTML. I've never used it. JAKE ARCHIBALD: Oh, I love insert adjacent HTML. SURMA: I always do create element and set an HTML something. JAKE ARCHIBALD: Yeah, and I quite often end up doing that, or you're using some sort of library that's essentially making it easier for you. But for the sake of a slide-- and this is an old Microsoft API. This was one of the non-standard things that went into Internet Explorer blah, blah, blah four. It could be five, five, five or something. It was in that era somewhere, but they standardized it because it is actually a pretty useful, very weird API. You can see I want it to go after the end of the current script. That's how it works. And then it'll just, yeah, parse it as HTML. SURMA: Disgusting. JAKE ARCHIBALD: Disgusting, but for this case, it was actually quite useful. I was quite happy with it. Anyway, have you seen this type of thing before? SURMA: Of course I have. JAKE ARCHIBALD: It's disgusting. SURMA: It is. JAKE ARCHIBALD: So what is happening here is they're trying to load jQuery from some sort of CDN in the hope that it will already be cached because they've used it on a different site or whatever. But some countries don't have access to particular CDNs, or sometimes the CDN is down or something. So you end up with this little script, like hey, you're going well. If jQuery's not there, then I'll load it from my own server instead. SURMA: Document.write. They should be using insert adjacent HTML, shouldn't they? JAKE ARCHIBALD: They should be using-- well, the problem with that is that would behave differently, because that wouldn't load the script synchronously. SURMA: Oh, it would be an async. JAKE ARCHIBALD: It would be an async script. So that's why they use document.write, which is horrible. We've got a little script escape again in a different version of that there. So I'm less excited about this feature. Because my response to this would be don't load jQuery from CDN. Just load it on your own server, because then you're not going to have the-- SURMA: Especially-- Safari already double-keys their caches. No other site can put something in the cache for you on Safari anyway. Don't allow it. JAKE ARCHIBALD: And Chrome as well are doing the double-key thing. SURMA: Yeah, don't. JAKE ARCHIBALD: And you're going to hit a connection setup time for this other-- SURMA: Yeah. JAKE ARCHIBALD: OK, we think it's bad. But do you know what? SURMA: Let's talk about it. JAKE ARCHIBALD: The [INAUDIBLE] maps have a solution for this. As I say, I'm not massively excited about it. But what you can say is jQuery, and you can give it two URLs. SURMA: Also, we'll try the first. And if it fails, we'll use the second. All right then? JAKE ARCHIBALD: Fair enough. It's in there, so I just wanted to mention it. Here's one I'm a little bit more excited about. SURMA: Oh, it's a roller coaster of excitement. JAKE ARCHIBALD: Yeah, I know. It's just brilliant, isn't it? So here I'm loading foo, which is pointing to foo version two. SURMA: Oh, because we are past version one now. JAKE ARCHIBALD: Past version one of foo, but I'm also using comlink. SURMA: Good man. JAKE ARCHIBALD: But comlink also uses foo. But it expects version one. What are you going to do? SURMA: Ghostbusters? [LAUGHING] JAKE ARCHIBALD: Ghostbusters? That doesn't work. That doesn't fit. Shut up. Right. In this situation, here is what you would do. You've got this scope section where you're essentially providing exceptions to the import section. So for any modules that are under this directory, like onwards that have that sort of URL prefix. SURMA: Well done them that they thought about this. JAKE ARCHIBALD: There are exceptions there. SURMA: So is that something that we think will happen, that libraries will stop bundling their dependencies and just leave them as raw identifiers and leave it up to you as the final app developer to actually bend the arrows the right way that every import points to the actual correct file? JAKE ARCHIBALD: I think that's the dream. I think the dream is to find a way to turn the node resolution system into something that can be described by this import map. SURMA: Yeah, I guess you would expect bundles to output this for us. Right? JAKE ARCHIBALD: Yes, absolutely. SURMA: Because they already do the whole analysis and do everything. It's like, here's your input map. Just put it in your HTML. JAKE ARCHIBALD: And I think those libraries already exist. People have experimentally gone, and we can generate an import map based on the project structure. SURMA: Yeah, I know that the rollup bundle object pretty much contains all the data we need to do this. JAKE ARCHIBALD: Yeah. Yeah, so it's easily done, which is great. Yeah, whether a human would be writing this or whether it would be generated by a bundler, who knows. Final thing-- and this is one of the things I'm actually most excited about. SURMA: Oh boy. JAKE ARCHIBALD: Import scheme. SURMA: Right. So that basically says so any old element that takes URLs can now take something with an import scheme and it will look it up on the map? Is that what is happening? JAKE ARCHIBALD: That is it. That is exactly it. It's that anything that supports URLs-- SURMA: So it's the same thing then, that I can prevent invalidation of the entire resource. OK, here. JAKE ARCHIBALD: Works in CSS background images, works anywhere you can use URLs. SURMA: Nice. Oh yeah, it's a scheme. So anything. JAKE ARCHIBALD: Yeah, it would even work in fetch. Yes, yeah, absolutely. Yeah. There is a slight problem with relative URLs. Because especially if you're in CSS land, it knows it's relative to the CSS file, because that's how referrers work in CSS. But if you're in a script and you do fetch, any relative URLs are relative to the document. SURMA: I'm going to derail this for a second, because paths drive me mad on the web. I like that rollup. When you bundle it, everything just ends up in a root folder. There's no folders anymore. There's no sub directories. Everything is just dumped into one record. There's no clashes because they have hashes in the file name. It makes things easier. JAKE ARCHIBALD: I would say for anything that is not going to be user visible, I would tend to agree. Obviously, we like good URLs. SURMA: Right. You shouldn't sacrifice that. JAKE ARCHIBALD: There are things that have got to appear in the URL. SURMA: But basically what I have, I have sub folders for the index HTMLs of my blog post, but all the images in the blog post are back in the root folder. So every URL, every image included is just a slash something something. JAKE ARCHIBALD: Absolutely. Yep. SURMA: And it makes things simple. JAKE ARCHIBALD: But it means that in cases where it's going to be relative to your document rather than relative to the module, the proposal is to have something like import.meta.resolve, which will take a relative URL, and it will do it relative to the module route. SURMA: Cool. You could even do things here. Like, this is actually really good for progressive enhancement when you want to do like, oh, does this browser have WebP support, and you can bend the import the right way. I mean, we have picture element and everything. I know that. But now you have programmatic control over it. JAKE ARCHIBALD: Well, do you know what? I'm glad you said that, because I realized there was a little bit I was going to talk about earlier and I forgot. In terms of progressive enhancement, this model where you're saying, like, foo.mjs to the hashed version, you could ship this to browsers that don't support import maps as long as you also have foo.mjs in your server. So you would have this URL, this on your server, which has the full caching headers, and then you would have this on your server as well as a fallback, which had no cache. SURMA: So old browsers aren't excluded. They can have worse loading performance, but they're not excluded, like the thing still works. JAKE ARCHIBALD: So maybe when it gets to most browsers have this but some still don't, then that's a switch point, and you've got a progressive enhancement. SURMA: This is really cool. JAKE ARCHIBALD: I'm really excited about this. SURMA: So am I now, I think. JAKE ARCHIBALD: I'm sure it will change a little bit before it reaches browsers properly. SURMA: Oh yeah. Yeah, I think it's very important, like, this is not happening yet. JAKE ARCHIBALD: No. SURMA: This is an experiment. At this point, it's in Canary. It's unstable because we have an origin trial, but it's not enabled and stable by default. There are still standards going on. There is a discussion going on. We should link to the proposal and stuff so people can weigh in if they want to. JAKE ARCHIBALD: And again, I was going to say we're looking for developer feedback on this. Do you like it? Do you hate it? What do you like? What do you hate? What do you think should be different? And now is the right time to be letting us know, yeah, all of that stuff. SURMA: Win. [WHOOSHES] Don't pretend like you have muscles. [LAUGHING] JAKE ARCHIBALD: Thanks, mate. [GROANING] I've got strong fingers, these typing fingers. SURMA: Every day exercise. JAKE ARCHIBALD: Everything else is just rot. [LAUGHING] Yes, that's it. I can't.
Info
Channel: Google Chrome Developers
Views: 15,424
Rating: undefined out of 5
Keywords: Chrome, Developers, Google, Web, http203, http 203, google chrome developers, GDS: Yes;
Id: yOcgGSCrn-c
Channel Id: undefined
Length: 20min 16sec (1216 seconds)
Published: Wed Sep 11 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.