Check out a free preview of the full Vite course
The "Library Mode" Lesson is part of the full, Vite course featured in this preview video. Here's what you'd learn in this lesson:
Steve explains that Vite is great for creating open-source libraries, especially if you're working with TypeScript or different file types. How to configure Vite to build a library, including specifying the entry point, setting the library name, and configuring external dependencies, is demonstrated. They also show how to optimize the library build by excluding unnecessary dependencies like React.
Transcript from the "Library Mode" Lesson
[00:00:00]
>> Let's talk a little bit about building libraries with Vite. There's a lot of reasons you might want to build a library, maybe you just want to create an open source library, great. Vite is really great for that, especially if it's like, I've got TypeScript or whatever, or I'm working with a bunch of different file types.
[00:00:17]
We can generate files that are regular all JavaScript. And as I said before, at the current moment, we live in a world where the JavaScript ecosystem is somewhat split between Common JS and ES modules, so maybe you wanna output both, right? And maybe you wanted to write in TypeScript, or maybe you're making a design system and you wanna actually output components with the CSS, so on and so forth.
[00:00:45]
Now, if you think about this, this shouldn't be all that hard, and it's not. But what has been the entry point for every single Vite example we've done so far? Index.html, right? Well, how's that gonna work with the library that you're building, right? That doesn't really make sense, right?
[00:01:03]
Cuz Vite's main purpose is to go ahead and try to build client side apps. That said, to no one's surprise, it does have a mode set up for making libraries. Would anyone like to venture, I guess, what the mode for creating libraries is called?
>> Library.
>> Library what?
[00:01:29]
Mode to creating libraries?
>> Library freeze.
>> We'll go with that, library freeze, library mode. I don't know if they're actually specific on if it's mode. I think it's called library mode. We'll find out, cool. And basically, we just have to kind of opt into a few extra features, and this is, again, us going into our configuration again for the first time in a while.
[00:02:01]
And so, for instance, I might do with components and then have you all do with one of these files, we'll see. The beginning piece is somebody's. Let's go into those components I had before. Or I have the other repo, the Vite components. Let me go in there. Vite components, I'll just open that up real quick and we'll take a look.
[00:02:35]
Just make a new branch now called live coding, no. The live coding, awesome. All right, so in here I've got, it's based on the React template. The only things I put in here is the world's simplest button with some classes, and an input field, right, to kind of be the basis of a design system, right?
[00:03:04]
If I wanna make a library full of these files now, it could be components, it could be just a bunch of utility functions, right? What we do with the library is totally agnostic, but it's the same basic idea. There are just a few things that we need to kind of put in place.
[00:03:23]
So in here I do have a Vite config cuz we had React in here. This is very similar to what you saw when we created a template. One of the cool things is that the Vite team understands that if you make a library, you might also want to make a website for that library, or at least run a development server where you can see the components or something along those lines.
[00:03:50]
And so, it does allow you to both have everything we have at the index.html file, and then also that it could even just be storybook or something along those lines, depends on what you're doing. And then also, actually, instead of using HTML file as the entry point, I actually give you the ability to specify, no, no, like what you're used to see in web packers and all those, like start at this file.js, and then the imports from there, and then build it into a disk directory as we would see.
[00:04:20]
And what we're gonna do is we're gonna try to build it for both Common JS and ES Modules as well, and you can do other formats if you really want to, I don't. And you kinda work through the process cuz the initial step is easy, but then getting it fully in a way that you can consume it takes a few more extra steps.
[00:04:38]
So, in here there is also a build option. There's a whole bunch of things we can tweak in here, like you won't tweak that many. As you can see, we've gotten a lot of power so far out of doing very little to our Vite Config other than popping in some plugins.
[00:04:52]
But now we've become the kind of people who want to go ahead and build some libraries. So with this, so we can say build, and then to get into library mode, we just say lib, that's why I don't remember, is it library mode or library freeze? What are you angry about?
[00:05:14]
Yeah, it just doesn't like, I haven't put anything in here. Where we give it an entry. So I've got this index.ts which is just exporting out these two components, that seems like a good place to start. And so we'll say, entry, and can I just do a dirname in this file?
[00:05:33]
I forgot, dirname, that result's gonna come from path. Path dirname, and then I'm gonna say source, and then what, components, cool, and I give my library name. What's the name you'd like design system be? Anyone have a strong opinion? There's thinking faces, but I hear no, anyone suggest?
[00:06:01]
What's that?
>> Just do Frontend Masters.
>> Frontend Masters, that's it. I'm in charge of the Frontend Masters design system now. That's ridiculous, but it'll work. And then fileName, and this is what we want the output file to be. Frontend master's design system, let's give it the name of it.
[00:06:30]
And let's see what happens if I do an npm run build now. You can see that it produced two files, one of dot js, that is my ES module, and another one that is a UMD, which is universal module declaration. It's one of those things where you didn't realize we were gonna ever say the letters out loud.
[00:06:56]
That sounds about, right? I know the U is universal, the M seems like module. And then definition, I don't know, who knows? Somebody definitely knows, I can see this in the chat, and then you can tell me in a second, or somebody can live follow up. And so we get these two files, and also style.css, cuz that's actually pulled in there as well.
[00:07:15]
And it will generate those files for me, right? And you can look in here and, yeah, you know what? Let me tell you a problem with my design system. It's 19 kilobytes. Let's look at the code that I'm shipping. That's my button CSS. My input's got even less cuz I got lazy.
[00:07:40]
And that shouldn't be 19 kilobytes. Why is it 19 kilobytes? Cuz we've decided to bundle in all of React. Which makes sense if you think about it, right? Because in a lot of these build tools, React is implicitly also imported. If you're using JSX, you used to have to do the import React in every single file.
[00:08:11]
If you realize, why you don't have to do that anymore, it's because they do it for you. So we've bundled in all of React. Is it fair to say that anyone consuming my new awesome design system of React components is using React? How badly do you think they want a second version of React in their application?
[00:08:34]
Those could potentially be a different version of React, completely. They probably don't, right? But Vite is doing what you told it to do! It's bundled everything up for you just like you asked, cuz it doesn't know about your dependencies that are needed unknown dependencies, it just knows you said bundle this stuff up, you require stuff.
[00:08:55]
I did what I was asked, right? And it's been doing a lot of tree shaking for you, a lot of code splitting on your behalf, so we're gonna cut it a break. We just need to basically tell it what exactly we would like to do in this case.
[00:09:10]
And so, that's relatively easy. All we have to do is give it a little bit of information. Now, we talked about in the beginning, when we're in development, it's the us building a lot of stuff, you can tweak all the options ES build. And when we build for, quote unquote, production or the output of my library, then we're using RollUp, right?
[00:09:29]
And Vite is just standing on the shoulder of these giants and has a bunch of options in here. And so, well, we're going to say, hey, RollUp, let me tell you what not to include, React, right? Because we're gonna assume that they have React as a pure dependency, and we're not going to bundle it.
[00:09:44]
And so we do need to say that out loud. So here we can go as well into, what is it? RollupOptions, and we can basically say what the external dependencies are. And so for the external dependencies, we're gonna say React. We know it's not just React that we've got to worry about.
[00:10:14]
I don't think we actually pull in React DOM. And then there's this, if you're using React, you gotta worry about this one. If you're using like Vue or something, you're making a Vue one, you don't have to think about this stuff. React.js runtime, we also just don't want included either, right?
[00:10:31]
And theoretically that will work for a lot of the UMD declarations. And there's other options in there too, if I'm remembering correctly. Yeah, you can see in Common JS, ES Modules, UMD, and then IFIS, which are what immediately invoked function expressions, like the way we used to do modules before we had modules, which is just a function where you pass the stuff in.
[00:11:00]
And so just need to know the names of the things that it should expect to be globally available. And this really only matters to some of those other formats, but we're trying to be good citizens here. And we'll say output, and we'll just say that the globals are.
[00:11:18]
And it's basically the name of the import and then the global, we should assume React is available if we're using these components. So we'll say, we would otherwise import React, assume that there is a React object that has already been imported by the consuming library or the consumer.
[00:11:36]
We are the consuming library. And we'll just say, react-dom as well, right? And now let's go build again. Hey, look at that. We went down from 13 kilobytes to 0.5 kilobytes, right? Cuz we just didn't put all of React in there as well. There is a little bit more work that we need to do though.
[00:12:06]
As you noticed, one of the nice things is if we look at the build, those CSS modules are bundled in there as well. Here we'll save so we get a little bit. So we get all of that for free and they are scoped, which is pretty cool. I, for some reason, decided to base style some stuff.
[00:12:23]
We could turn those into classes and it would work too. So those will be global because they were just on the base. But our CSS modules are, in fact, scoped as appropriate, and I'm unclear how well we can see. But we might have one issue that we need to deal with, which is we've got the classes in here, it looks like I might have to squint in a second and figure out.
[00:12:54]
It looks like that 0.5 kilobytes was a little bit too small in this case. So I'm gonna peek at this real quick and see if I made an obvious boo boo. So we go ahead and run our build, and 0.5 K looks a little small. And if I look in here, there ain't nothing, right?
[00:13:14]
And so, I mean, there's a JS runtime. And maybe we need to tweak that as well. But if we look, the issue is that the way that I have this index.tx, we're actually exporting the star, but the defaults are not necessarily included. So what I need to do, this is why I hate default exports by the way.
[00:13:36]
Who knows what I was thinking at the time? And so, we'll go in here, we'll just export both of those. And again, we're gonna squint at minified code for a second. But this looks a little bit more crap. We don't have React, right? All right, looks closer to a kilobyte, and we can kind of see, if we squint hard enough, those are the button classes.
[00:13:57]
There's a dangerous prop that we saw earlier, right? We've got the minified version where we've got the button, we've got the input kind of like in this one file in this case as well. And we've got the styles, as we saw before in here too, and so that's all nice to have.
[00:14:20]
And so we are at the beginnings of, let's do this, react/jsx-runtime in there as well. I actually don't know what that resolves to, so we're gonna leave it. And so, all right, we've got all of that kind of in place cuz it wasn't actually pulling the library, it was just a reference to it, which is probably fine cuz it's one with side effects.
[00:14:46]
If you looked at when we saw the bill before, I'll show you, it wasn't storing it into a thing. It's got the JSX in there. At this point it's not bundling it in there, so I'm willing to say that for this point I'm cool with it.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops