Vanilla JavaScript Projects

Building for Production

Anjana Vakil

Anjana Vakil

Software Engineer & Educator
Vanilla JavaScript Projects

Check out a free preview of the full Vanilla JavaScript Projects course

The "Building for Production" Lesson is part of the full, Vanilla JavaScript Projects course featured in this preview video. Here's what you'd learn in this lesson:

Anjana demonstrates how to build a production version of the application. Vite will provide errors when JavaScript features incompatible with the targeted browser runtime are used. An IIFE is used to enable support for top-level await.


Transcript from the "Building for Production" Lesson

>> So this brings us to the end of part two, where we have now done a developer workflow in the dev mode here. And maybe just to round things off, now that we've got the thing that basically works and we wanna ship it, right? Go ahead and ship it off to production.

What we can do is Ctrl+C to get out of our npm run dev server and instead use that other command, npm run build. What happened, it's the top-level await. Okay, there's some config there that's happening. Where am I doing top-level await again? Okay, does anybody remember about a workaround for when you don't have top-level await?

So let me just back up here. There's a couple things we can do. One is, the configured target environment. Which is, this is part of the Vite build tooling, is essentially, when it's running, it's not really trying to match all popular browsers and environments and things like that and make all of the compilation decisions of, that doesn't have that in that browser, that's not supported.

For example, when we're poking around MDN, and we see at the bottom this browser compatibility table of a lot of these features. Right now, this is green across the board. But if we look at something else like XR, WebXR, something experimental, yeah. So once we start getting into experimental things, we'll see that not all browsers support the same stuff.

On MDN, this is also often, there's little labs, like experimental beaker, no, flask, whatever. [LAUGH] That tells us that this isn't a widely supported feature, so it's not green across the board. So for example like this, I don't know WebXR stuff, for example, is pretty new, it's extended reality, whatever.

Point being, when Vite is building for us, and this is a good note about like dev versus prod, or production, right? Is it's going to kind of target all these different environments. And if it sees that stuff like top level await isn't actually supported, even when I have a script type module and all that stuff.

And maybe it's even compiling away that modulification, that's gonna be a problem. So good note about the difference between, it works on my machine and it's gonna build for the web. And again, an important reason why a lot of these tools, like the building, the build process here, which I believe uses Rollup, are going to do some of that work for us of try to catch some of the ways that it might break on other people's machines that don't happen in our particular dev environment.

So, however, there is a way that we can get around this top-level await that we briefly mentioned earlier. Does anybody remember, yeah?
>> IIFE.
>> IIFE, let's get IIFE with it.
>> Don't ask me what it stands for, I forgot.
>> So IIFE, Immediately Invoked Function Expression should work.

What it will do, the way it works, let's find out. I mean, I say should, but [LAUGH] at this point, I don't know why you believe anything I'm saying. [LAUGH] No, just kidding. The way it works is we declare a function, an async function in this case, within, not the top level scope, but within a new little scope that we get by evaluating it within parenths.

So this can be async function, I don't know run, or it doesn't even need a name. And then we do the stuff we wanna do in the main part of our script. Okay, cool, now if I go back, this is probably, I have stopped running the dev server, right?

But we're not trying to do the dev server, we're trying to run the project. So if I run the build, okay, the build is satisfied, but we're not quite were there yet. Because if we look closely, we declared a function inside of these parenths and we evaluated it.

But now, at least the build succeeded. And again, there is a version of the local server for the built directory, which if you are keen-eyed, you might have noticed. There is a new little folder in my project now, it's called dist. And that's a default of the config.

We haven't quite gotten into all of the configuration options for Vite, but you can go read about it on their website. But so dist is where essentially the production site, which is just assets and index and an SVG. The assets having our little JavaScript all, goodness, would you remember to wrap?

Okay, this is what it has output. That is not something we wanna be using in our day-to-day as a developer, right? I don't wanna read that. Do you wanna read that? No, so this, however, the JavaScript don't care. It doesn't really matter to it, what we name stuff, or how many whitespaces there are, that sort of thing.

So anyway, now I can run a server that loads that, the stuff in the dist directory, with npm run preview. That was our third script in our package.json, which is essentially, now it's gonna be on a different port. It's 4173 for whatever reasons. Okay, so now it loads.

Let's see, do I have errors? I hope not. We do indeed. Cool, cool, cool, cool, button is not defined, [LAUGH] great. I did not move the addEventListener into it, so there was no button. Okay, thank you JavaScript console, but we can see that this is running actually, not what I have in my dev folder.

So this server is still running, but this page hasn't updated because I didn't rebuild it. So it's not listening for those changes like the dev server is. So instead, what I can do is build again, and then preview again, see if we have a button. I had to refresh cuz, again, it doesn't have the fancy reloading.

It seems like it knows what a button is now, excellent. It doesn't do anything yet, though, because we have missed a crucial ingredient of the immediately invoked function expression, which is the immediately invoked part. So what I have is a function expression that is immediately evaluated between these parenths, but it is never called.

So how can I do that?
>> Parenths at the end, right before the semicolon?
>> Parenths at the end, yes, and?
>> It's like there's no parameters.
>> Yeah, because we don't have parameters, it looks kinda weird. But again, it's returning a function, and then we're calling that function.

Let's see if it works, [LAUGH] okay? So now we've got to make some changes, so we build, and we preview, And we reload, and okay, it's asking me for permission. That seems like a good sign. Cross your fingers for me, and send me all of your shamrocks and four-leaf clovers and whatever we use for, hey, all right?

We have the most amazing selfie, my goodness, okay, all right, that we have ever seen. [LAUGH] And I hope you all are having as much fun with these selfies as I am up here. [LAUGH] I feel like I need like some kind of prop here to involve in my selfie.

But in any case, we're just going to give ourselves a thumbs up for having built a production-ready site that took advantage of a whole bunch of these fancy features for the browsers that know about them and also workarounds for situations where we can't do the fancy thing. And it hopefully has been a perhaps long and winding road, but a road that ends with a selfie.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now