596

April 3rd, 2023 × #javascript#webdev#tooling

The New Import Map Standard

Explains the new import maps standard for aliasing files and paths in JavaScript projects. Covers how to use them and browser support.

or
Topic 0 00:00

Transcript

Scott Tolinski

ghee. Welcome to CIT Tax. On this Monday, hasty treat. We're gonna be talking about a feature that just arrived in pretty much the last of the browsers that it needed to arrive in, and we're gonna be talking about import maps.

Scott Tolinski

This may be something that you've seen around or heard around or maybe you've never heard about it, but it is, you know, it's related to the new JavaScript ESM syntax. So we're gonna be talking all about what import maps are and more. My name is Scott Talinski. I'm a developer from Denver. With me as always is, Wes, the hot tips boss.

Wes Bos

Yeah. I just got this, new, like, neon it's not neon, but it's LED, but looks like neon sign in my office,

Scott Tolinski

and it's so cool. I'm so happy with it. Yeah. Hey. Isn't isn't that like a wonderful technological advancement that We don't actually have to have real neon Yeah. Anymore. You could just do LEDs and have it look the same. I mean, LEDs, Like, really, I I know it's probably not low key, but, like, have completely transformed the world in so many ways. Everything.

Wes Bos

Everything. Yeah, it's so good. The only thing I don't like about LEDs is that light fixtures are just garbage now whenever they whenever they die, right? They can't replace the light bulb. They're just disposable.

Wes Bos

Yeah, yeah. I'll take it for the energy savings and the ability to literally put them in anything. Yeah, totally. And they dim they dim decently well, too, depending on what you get. Yeah, it's I went through that with my office It's like there's like a weird combo of high quality lights and high quality dimmer switches. Mhmm. And you should never cheap out on either of them. Yeah. Or else you're gonna have some. The other is a buzz like I have we put some in. They don't turn off completely. They don't dim correctly.

Scott Tolinski

A lot of things. Yeah, yes, annoying.

Topic 1 02:17

import maps explained

Wes Bos

But let's, let's get into import maps here. This is something that has just dropped in Safari Technical Preview. Now they're in all the browsers. I thought we would do a quick show explaining what they are, how you use them, what they what they look like and like what about TypeScript, Deno, Node, all of that stuff as well. Yeah, that sounds lovely.

Topic 2 02:39

aliasing paths

Wes Bos

Import maps. This is actually going to be really helpful for, I think, probably everybody listening. They are the ability to define, I'm going to call them aliases for paths in your project. So if you have like Utils. Js or you have a folder called DB and you got 6 or 7 files in there.

Topic 3 03:01

aliasing node modules

Wes Bos

Often when you're requiring files. You got to do that dance where you go up 2 levels, over 2 levels, and down 3 levels. And it's kind of annoying, right? And Scott has said himself for a long time, you've been using the, what, the TypeScript version of this where you just have the at in front? Yeah. And and it's mostly Vite at this point. And and, honestly, the way that SvelteKit does it is really neat where you add your aliases in the SvelteKit, And then it generates all the TypeScript

Scott Tolinski

config you need, and it generates the Vite config that you need. So that way, you only have to write it once. In the past, I was having, like, a separate Vite and a separate TypeScript just to get them both on the same page. But, yeah, I've been using, aliased imports for a long time because, like you said, that whole song and dance about having to Recognize where you are and where you're going. And if you move a file, sure, Versus Code 9 times out of 10 these days will update your paths correctly, But sometimes it won't, and sometimes it can be frustrating that it doesn't do that. Or sometimes you end up with a forward/.forward//.forward/.forward.

Scott Tolinski

Like, you just just this long, long, long path. You've dialed it in. So this just makes everything cleaner. They feel like internal modules is really what they feel like. Yeah, exactly.

Wes Bos

So this is a new web standard. It's in all of the browsers and you will be able to specify either a folder files so you could alias utils to.

Wes Bos

Forward Slash. Forward Slash.

Wes Bos

Whatever.

Wes Bos

Oh, and then you can also you can alias. And this is super helpful, especially in Deno ESM world. You can alias HTTP paths. So if you have a file on a CDN somewhere that you want to import, then you don't have to say Import react from httpcolon/esm.

Wes Bos

Sh or unpackage or ESPN. Like there's all these like CDNs out there that will host all of NPM for you and you can require it directly for it from it because that's part of the mspec that you can just import stuff from a URL.

Wes Bos

However, it's annoying, especially if you have to do that through 8 files. You know, then that file name has the package number in it, and that gets kind of unmaintainable.

Wes Bos

So the solution to all of this is an import map where you declare a little bit of JSON in your application.

Wes Bos

And you say, okay, when I import things from these names like raw, Just like I import whatever from React or import whatever from Svelte. If I want to import something from a local file or a remote file. I can just use that URL and the browser will know to look at the import map and say, They use the word utils or money or svelte here, but I know to actually go get it from this local or remote file.

Topic 4 06:03

import maps are like directions

Scott Tolinski

Yep. And and one thing to, you know, think about in the term map here. Right? We have an important map. You'll hear the word map in programming a lot. And it's almost always kind of like a map is is almost like a direction to somewhere else or or that regard. Right? You have, what are they? What are the, source maps? Right? Yeah. A source map is basically a map to show you from your compiled code to your non compiled code and this is basically a a direction to say hey here's a path And this is the path that you should resolve. It's basically telling you where to go at any time so you can just keep that in your brain is like, hey. I'm I'm looking at a map here. That's what these things are doing.

Scott Tolinski

How do you feel about the syntax for this thing, by the way?

Topic 5 06:50

syntax thoughts

Wes Bos

It's good.

Wes Bos

So it's Mhmm. It's JSON.

Wes Bos

Yeah.

Wes Bos

And Yeah. You open up a pair of curly brackets. I don't love writing JSON, but I understand why it's JSON because it has to be statically analyzed, right? Like, it can't be programmatically imported or whatever. So open up curly brackets, you have the keyword import.

Topic 6 07:11

import map syntax details

Wes Bos

And then inside of that, you have your keys are going to be your like aliases, and then the values are going to be either local or HTTP paths where it can go. I even wonder if you could do like like a like if you had a floppy disk that would that work? I should get I should get a floppy disk for my to Thunderbolt and try plug it in and put some JavaScript on the floppy to see if I can a good alien

Scott Tolinski

ESL. I don't see why you couldn't. I mean, this is a bad. Right?

Wes Bos

Yeah. At floppy?

Scott Tolinski

Yeah.

Scott Tolinski

At floppy. Yeah. That's great.

Wes Bos

That that's actually another a good point is that a lot of people will like to note them with a use what? An at sign at the front? Yeah. I use a dollar sign. Okay. And then that's just kinda convention I picked up from SvelteKit specifically.

Topic 7 08:03

distinguishing local vs external

Scott Tolinski

I've done several different things. Sometimes I've done an at sign.

Scott Tolinski

Sometimes I've done like a at level up even though that's like Feels like it's an NPM package, which is why I've moved away from that.

Scott Tolinski

Anything that you can do to distinguish your local paths your local module paths from, you know, external ones is going to be like a win for clarity when you're working in your code because what you don't wanna do is you don't wanna be looking at these maps and say, like, alright. Is this a is this a, a package coming in from NPM. Is it coming in from something local? Is it map from somewhere else? You know, you can have a system. The dollar sign does work really well. I have, like, dollar sign utilities, dollar sign DB, dollar sign types. You know? I have have those things set up, and it it, For the most part, it's it's done very well for me in terms of being able to recognize what's local and what's not. Yeah. I I also I forgot to say the JSON of the import map goes into a script tag with the type of import map in it. So this is something you define in your HTML.

Wes Bos

It's generally your entry point to your application and you put that in there and then any scripts that are loaded on that page will know to use that import map when when running it. And this is because strictly because, you know, this thing works without

Scott Tolinski

bundlers, without package.json.

Scott Tolinski

It works just straight up in the browser because you can now use imports in e s m just straight up in the browser. So there has to be a way to define it that the the browser can understand easily. So that that's why that is like that. In case you're wondering. Another question that a lot of people have is like, what about

Topic 8 09:24

dependency resolution discussion

Wes Bos

dependency resolution? You know, like if you think about like, okay, this is great or if you get a utils file. But like, what if I'm already using node packages and whatnot? Some packages will publish a version that has like no bundled version. And then also when you do your bundling, You can set modules to be external. So meaning that if you don't want your or ESBuild or whatever to actually bundle the dependencies and say just look them up yourself, Then you can mark them as external, meaning that it won't include them as part of your final package. And it's saying I'm going to leave this up to the browser or the the JavaScript runtime to figure out where those specific things are. Yeah. So kind of back to

Topic 9 10:30

bundlers discussion

Scott Tolinski

what we're talking about with package.json or or, you know, modern JavaScript.

Scott Tolinski

Like, what about, like bundlers. Right? The so much of our work these days has been around needing a package manager, needling a needing a bundler to resolve those packages and bring them in and bundle your code together so that it all works. Does this mean that we, can now just use import maps and bring things in from package dot or or node modules folder directly without having a a bundler that

Wes Bos

compiles it all and brings it all in for us. Yeah, I made a TikTok on this and I said, like, we're probably a long way away from not having to use a bundler, but this is Certainly a step in the right direction. Yeah. It's a step. I don't know if that was the right thing to say because the more I thought about it and the more I got feedback on it, people Sort of saw this as like this is an alternative to a bundler. And in reality, this works just great with all of your tools and all of your bundlers and everything. It's just a way for you. It's a standard way to define what your aliases and what your import lookups are going to be in your JavaScript code. And whether you run that raw in the browser, which works great, Or whether you actually do end up running it through a bundler, it still is very nice to be able to alias these things in your application. So I probably don't see this as a bundler versus not bundler thing, and I probably should have worded that a bit different. I think it's more of a this is a standard to define how things are looked up.

Topic 10 12:11

import maps work with bundlers

Wes Bos

And isn't that great? Because now

Scott Tolinski

any tool and raw browser can use that. Yeah. I mean, ultimately, though, it does it does mean that There are some instances in which in which you might use a bundler before that you might not have to know especially for early projects, small projects, little hacked together things you wanna throw together something and just toss in an important map to resolve some of your dependencies like that. That seems like that that's totally a fine thing to say. I mean, I don't I don't get the pushback on that. But Yeah. Yeah. Totally. And, like,

Wes Bos

eventually, maybe we will be at a spot where we don't necessarily need the bundler.

Wes Bos

Like, what is 1 spec that is a browser standard that made all of our tooling better? ESM, right? ESM is a web standard.

Topic 11 12:59

standard across tools is good

Wes Bos

And even though we still use all of these amazing tools like Parcel and Vite and Webpack. They all picked that up and made it part of their tooling chain. And isn't that beautiful that we have a standard across it. So wouldn't that be nice if we had a standard for aliasing across all of these tools? Absolutely.

Scott Tolinski

And all of those things they they made our our bundles that brought their their whole development process faster because, you know, the computer is having to do less for us now because the the browser can do a little bit more. And not not to say that this will do that, but, you know, who knows? Maybe maybe, it will open up some improvements our tooling that we can just take advantage of in our our day to day work. So let's talk about, using this with things like Deno and Node. Now I I've Actually, Wes, I just started a new project, and I used I chose Deno for it, just because you know, I wanted to write some TypeScript. I wanted to get it up and running quickly, And I wanted to just give Dino a a quick try, and I was so pleasantly surprised. Well, not pleasantly surprised. I I just say, Pleasantly, enamored with how nice the experience of working in Deno was. I was like, this is great. I I think I, you know, I think I would, start any small new project using the same kind of flow.

Topic 12 14:13

how import maps work in Deno

Scott Tolinski

So how do these things work with Deno? Is it is there anything fancy here that we have to be aware of? So

Wes Bos

Deno uses the import map spec as well, which is awesome. So, again, another win for Deno being web standards based.

Wes Bos

It goes into a file called importmap.json, and that will that will be looked up when you run your application via Deno. So that's awesome because it's there. So if I were doing this In a project that was server and client, I probably would just put it in importmap.json and then I would just pull that into my HTML template as part of my render, right? Because then then you can just have it in 1 file and pull it in wherever you want. Does this do away with the whole DEPstat

Scott Tolinski

TS thing in Deno?

Topic 13 15:04

import maps and DEPSTAT

Wes Bos

Yeah, it does. And for the longest time, that's kind of what I thought would be the package. Json of Deno is just you import something from a URL and then immediately export it or export from HTTP blah blah blah. But It's essentially your your package. JSON is essentially your import map where you are giving it a list. And also one further is Deno supports the npm colon prefix in import maps. Mhmm. So what you could do is your import map is instead of having to install something, you just npmcolon react, npmcolon svelte. And that you should probably put the SemVer version on the end as well because you shouldn't just be locked versions.

Topic 14 15:51

SemVer in Deno import maps

Scott Tolinski

Yeah. Yeah. Yeah. Yeah. So those of you who don't know what we're talking about, in Deno, there's no package dot JSON. And so because tons of that. The way that people have been doing it for a long time is to simply just, like you said, import something from the URL and then immediately export it, because that's how import and exports work. And that's great. It works fine. But at the end of the day, you end up having 2 different ways of doing things in Deno world versus node world.

Scott Tolinski

And now with the import maps, if you wanted to have an import map take care of that for you, you could do a kind of the same way. But, again, you're probably just gonna end up Still using package.json.

Topic 15 16:26

standards over conventions

Scott Tolinski

But at at least with Deno now, you have a standards way of doing it rather than just this thing that people started doing out of necessity. Mhmm.

Wes Bos

Also another thing that Deno did roll out a couple of weeks ago is they now do support the node package. JSON. A Much to most a lot of people's Chagrin? Like, grimace. Yeah. What's it what's it called? I think it's chagrin.

Topic 16 16:35

Node package.json in Deno

Scott Tolinski

Che Grin. Let me Google this. Chagrin. Yes. Oh,

Wes Bos

s c h a g r I n. Disappointment or anger, especially when caused by failure or mistake.

Wes Bos

Mhmm. And they have to kind of do that in order for people to move over from node More easily. So now they support it. But it's kind of tricky with the with the Deno stuff because you you look at it, you'll get, okay, I want it to work in Deno. But I also would like it to work in node.

Wes Bos

So do I just use node code? Do I just do everything in node and then run it, Indino?

Scott Tolinski

Yeah. Right. Well, I guess maybe. Yeah. Right? Hey.

Scott Tolinski

Right. Then it's at then at least you could choose where you're running it, I suppose. Is Node the new standard?

Wes Bos

It might be. I was I was actually looking into that with the, what is it, the new file system API.

Wes Bos

There's like a new file system API that's in all the browsers now.

Topic 17 17:46

new filesystem API discussion

Wes Bos

And it's just like, well, Shouldn't we have that in Deno now so that if I want to write a file, it would be it would work in Node? Because like now if you want to write a file, you have Do it in like a Node API or the Deno API or the Browser API.

Wes Bos

It would be nice to have like 1 API. And now there's a new there's a new spec for that. And I've written a couple of notes in the winter CG, which is the working group, And they're thinking about it. So apparently, it's like not fully fleshed out yet or it's like not doesn't cover all their use cases, but It would be nice to eventually again, like this import maps will have 1 standard file system API

Topic 18 18:31

filesystem API concerns

Scott Tolinski

browser and all the JavaScript runtimes. The the the file system API. Are you is it is it like what you would use in the browser for accessing the user's local file system? Is it that same API? Or

Wes Bos

Yeah, it's the What WGFS.

Wes Bos

Let me I'll link up the the winter CG proposal.

Wes Bos

But, yeah, it's for accessing, I think, either a sandbox file system in the browser.

Wes Bos

Mhmm. I think that's what it's for, not specifically for accessing the actual user's file system. Maybe it is. I have to look into it a little bit more. It was just just approved. Okay. Yeah. Oh, it was just approved. I was gonna say because there is that that,

Scott Tolinski

file system API in the browser already that I've done a little bit of work with and it's really neat to access the user's local file system.

Scott Tolinski

And I was wondering if this is the same one. I'll have to dive in. Yeah. I'm just reading the winter CG

Wes Bos

where I added it because the other thing people are saying like, well, Cloudflare is part of the winter CG, but Cloudflare doesn't have a concept of a file system.

Wes Bos

Right. There's no file system in Cloudflare. If you want to save something, you said you send it to a service.

Topic 19 19:40

filesystem API use cases

Wes Bos

So, like, how would that work? Possibly yeah. How could you

Scott Tolinski

does the whole thing blow up if you access the file system? Yeah.

Wes Bos

And like, how often in Node and Edge scripts and Deno scripts are you actually writing files to the file system? Usually not that often.

Wes Bos

But There's a whole all of tooling is writing file system. All the scripts I write locally to do things, that's that's file system. So it still would be nice to to have it.

Wes Bos

Anyways, let's keep going with node. So what about import maps with node? There is something in node which I didn't even know about until I started researching it. It's called subpath import, and it works very similar to how this works, except With Node, you must start it with a hash octothorpe hashtag is all the kids will call it.

Topic 20 20:13

Node and subpath imports

Wes Bos

And it works the same way in that you can alias files or directories in your note project. And this is actually super helpful. So it just goes in your package. JSON. It's called imports. Oh, yeah. Just like the spec. I've used this. Yeah. And then you could say like pound utils or hash utils is link to a JavaScript file or pound db star will be aliased to a DB folder and then all of the nested files inside of there, which is It's really nice. So it's almost the standard.

Topic 21 21:10

getting subpath into Node

Wes Bos

And then there are a bunch of threads and there's actually even some experimental code in there to look at getting this into Node, because if it gets into Node, the next thing that we're going to talk about is TypeScript.

Wes Bos

TypeScript has this thing called Pathaliases, which is what you're using, right? Totally. Yeah. So the Pathaliases is great, But it needs a bundler to properly work in Node. Js.

Topic 22 21:37

Pathaliases in TypeScript

Wes Bos

So it needs to be compiled. You have to do webpack or something like that. So if you're just doing straight TypeScript to JavaScript module.

Scott Tolinski

It doesn't doesn't work. Right? Yeah. And likewise, again, if you are using a bundler, you'll most likely need to tell the bundler,

Wes Bos

Like double define your aliases, right? Yes, exactly. That's what people are saying is that like, I have to set it up twice in like in my webpack or in my Vite again, and it could be a pain with just just doesn't recognize them.

Scott Tolinski

Oh, yeah, that's a whole thing.

Scott Tolinski

I guess that's another reason why v test is a thing. Right? That was, like, one of my whole things with the test for or jester's v test. It was like, I'm I'm my tests are not running the exact same config that my code is running, and that makes me very deeply uncomfortable.

Wes Bos

I should also say there are Vite, there's a Vite plug in to use your import map as well. Oh, really? It's great. So you feed that into your Vite config, which is again another reason why you should probably Put it in a JSON file so that you can easily import that and feed it into your vconfig.

Topic 23 22:23

Vite plugin for import maps

Scott Tolinski

Yeah, that's nice.

Wes Bos

Last Last thing we want to talk about is downsides to this type of thing. A lot of people say, what about X, Y and Z? Probably the biggest one people said is what about tree shaking? Because I Initially showed this as like a use it straight up in the browser.

Topic 24 22:59

tree shaking concerns

Wes Bos

And everyone says, Okay, but I'm not actually going to use that straight up in the browser because I need tree shaking and tree shaking is let's say you have a package with 7 functions and you only use 1 of those functions.

Wes Bos

Tree shaking will be smart enough to say, Okay, well don't include those other 6 functions in the final bundle. We need to keep it as small as possible.

Wes Bos

And the browser doesn't tree shake, right? The browser, the like multiple HTTP requests.

Wes Bos

To download a tree of JavaScript files is not an issue with HTTPtwo because the browser and multiplex the request. They can they can download all of those in one request, which is nice, but it doesn't tree shake. So The solution to that is, yeah, you probably still need a bundler to actually do your tree shaking.

Wes Bos

The other downside is there's no integrity, Which means integrity in JavaScript is saying every time you have a JavaScript file, there's like a hash that comes along with that file.

Topic 25 23:48

integrity hashes concern

Wes Bos

And if someone like if I had scott.com/cool.js and I was using that in my application, what's to stop Scott from swapping out the code on that file and gobbling up all my All my credit card payments or doing something malicious, right? So integrity means that when you load a JavaScript file. You also give it a hash.

Wes Bos

And if that hash doesn't match the file that's being downloaded because it's been changed at some point, then you know that there's some someone has been monkeying with the actual file, right? Like if you have version 1.2. Or there's just been a change in general. Yeah, but if that is true, then you should change the file path to be version 1.1.1 to 1.1.2.

Wes Bos

So if somebody actually changed But you should. Exactly. You, the developer, would have to manually go and do that instead of someone swapping it out from under you. So there's no way to do integrity with import maps.

Wes Bos

And In the browser, we have script tags with integrity. In Node. Js, we have package lock, which has hashes inside of it as well.

Wes Bos

So there is a proposal on how to get this working in import maps. I'll link it up in the show notes as well.

Wes Bos

Other downsides? I haven't looked into it yet, but my ESLint complains about not being able to resolve it. So there's probably some sort of ESLint plug in that will look up import maps. Let me search it real quick.

Topic 26 25:35

ESLint resolver plugin

Wes Bos

Oh, there we go. Hey, 57 downloads a week. Okay, so this is obviously very, very early on.

Wes Bos

It's called ImportMap ESLintResolver, meaning that like If you import something from a package, Esland will yell at you. It says, I can't find that.

Wes Bos

So this will look through your import map and and say, oh, I did find it. And it's because you used the import map. And then the Versus Code auto import. I also haven't looked into this, but It doesn't if you do the auto import, it does the straight up path.

Topic 27 26:09

VSCode auto import issue

Wes Bos

So I don't know how to make it work with

Scott Tolinski

Import maps. And that's the thing. It works really well with the Vite and TypeScript version of aliases, which obviously is the same thing, but it works really super well. Anytime I auto import anything. And that maybe not a 100% of the time, but 99% of the time, it finds my my package incorrectly uses their the import. And it's done that for a while too. It did that, back when I was using, not Vite. So it's been really good about this for a little while. I think TypeScript is really the the the key to it all, the fact that TypeScript is so smart about your code.

Wes Bos

Apparently, the Versus Code language server for Deno will respect your import map, which is good.

Wes Bos

So maybe that has something to do with the TypeScript language server again. So TypeScript doesn't know what import maps are.

Wes Bos

So again, hopefully it makes its way into Node, which hopefully means it will make its way into TypeScript, which hopefully means that It will be in in Versus Code eventually. So it's kind of early days. It's now in the browser. So hopefully we'll start to see in the next 6 months or so some stuff moving on all of this. Cool. Well, these are import maps.

Scott Tolinski

Wes, anything else that you have on import maps? I'm I'm really excited that this is is finally here. And keep in mind, it's it's in Safari technical preview. So with Safari, like, honestly, one of the biggest bummers about Safari is that you have to wait for the OS to update or the the user to update their their browser.

Scott Tolinski

But it's in the technical preview, so, you know, that that's good for us. That means that the next time anything gets updated, released for iOS and people actually update it on their phones, which for Apple. At least they actually do. Right? If you if you were to say this is tied to a version update in Windows, it would never get updated people hate updating their windows. But, users seem to update their Mac stuff fairly often. So, hopefully, that means we'll be able to reliably use this in some degree. And I don't know if I'll be rushing to use it, but it's nice to have the option. And it's nice that it exists, especially for for small little projects that you're going to hack together. Exactly. There. Also, I should also say there is a polyfill

Wes Bos

if you do want to use this in it. But honestly, the way I see it as This is probably just a really good thing for small projects, like you said, and it's a standard that we can now push into all of our tooling that will work Across the board. Sick.

Wes Bos

That's it. Thanks for tuning in. Catch you later. Peace. Peace.

Scott Tolinski

Head on over to syntax .fm for a full archive of all of our shows. And don't forget to subscribe in your podcast player or drop a review if you like this show.

Share

Play / pause the audio
Minimize / expand the player
Mute / unmute the audio
Seek backward 30 seconds
Seek forward 30 seconds
Increase playback rate
Decrease playback rate
Show / hide this window