Creating an Open Source JavaScript Library on Github

Adding & Configuring Webpack

Kent C. Dodds

Kent C. Dodds

Professional Trainer
Creating an Open Source JavaScript Library on Github

Check out a free preview of the full Creating an Open Source JavaScript Library on Github course

The "Adding & Configuring Webpack" Lesson is part of the full, Creating an Open Source JavaScript Library on Github course featured in this preview video. Here's what you'd learn in this lesson:

Kent walks through how to add Webpack along with the Babel and JSON loaders. He then creates the build scripts necessary for building the application with Babel and building the UMD version of the library. All the build scripts are joined with an “npm-run-all” script that will execute them in parallel. The code for this example is on the FEM/08.0-browser-build branch.


Transcript from the "Adding & Configuring Webpack" Lesson

>> [MUSIC]

>> Kent C. Dodds: Yeah, so there are a couple of used like I was saying. Obviously you need web packaging around this and then you'll need the babel loader and the json loader to be able to use those with webpack. And so those are the things that you would normally npm install, but we'll just stick them right in here.

webpack, and we could use the latest beta, but we do not actually need it, so we will use the latest version. We will also stick the json loader right here, and that version I think you all have installed is 0.5.4. And then there is the babel-loader, and the version you have is 6.2.4.

>> Kent C. Dodds: With those things installed, then we're going to alter our build scripts a little bit. So I'm gonna change this original build to be build:main, we would add another build that is build:umd. And yet another one, well, we'll build that other one here in a second, but we'll have other one to build a minified version of umd.

So here we'll use the web pack cli, and we're gonna specify an output file name to be index.umd.js. Yeah, and that's it, with that you should be able to run your build:umd script. Yeah, is there a question?
>> Tim: Yeah, did you cancel that one? Once the browser is support module loading does that remove the need for umd?

>> Kent C. Dodds: Good question, Tim. You don't need to use umd if you what you're distributing is consumable in every environment you care it to be consumed in. There is the principle, the application of that is, let's assume that browsers and you have six imports. Then you don't need to transpile the imports and exports or the six modules and you can just distribute that.

You might still be transpiling the next cool hipster features. And so you may still have babel in your build pipeline, but you won't need to transpile those things and you probably wont need umd. But until all of the platforms that you're delivering to support the way that you're distributing your module, you have to distribute your module in a way that's consumable on those platforms.

Does that make sense? Okay, sweet, so let's go ahead and run this npm, run build:umd. And we'll see, we'll get some output, index.umd.js and We'll go to our dist directory, and there they are. Let's explore this for a little bit. So this should looks slightly familiar. Here we're checking exports as an object and modules as an object.

So it's detecting CommonJS a little bit differently than what we saw before and then it's detecting amd in pretty much the same way. It's using the define API slightly differently, but that's not super important. And then it also is checking some other module style. I'm not even familiar with what module style this would be.

But then the default case would just stick it onto the global, so whatever this is bound to in the global name space. In the case of the browser, that'll be Window. And so, if somebody is not getting any new files in their disk directory, I would recommend running git diff FEM/08, for some reason it's not auto completing for me.

But that's what you want to diff against. I'm pretty sure that I should have all the branches. That's funny. Yeah, I'm not sure that I can help you right now with that, sorry. The build time is now five seconds for such a simple project, is that normal? Yeah, let's go ahead and take a look at that really quick.

So run time npm run, well here. Actually, we'll look at that a little bit later, cuz we still have a couple of more things to do. Okay, so let's ahead and we'll copy on this code, we'll pull open a browser window and just paste it into our console.

So it actually works. You can just put it right in the browser, right in the console. And because we told webpack that we want it to be called starWarsNames on window, we can say starWarsNames, and we get an object that has an all property, and also a random function that we can call and get random Star Wars names.

It totally works in the browser, which is pretty cool. And this is the unminified version. It's generally nice to distribute a minified version as well and we're going to add another script that is very similar to the previous called build:umd.min. And with this one, we're just gonna change one, well, two things.

We'll say index.umd.min and it will add the -p flag, which will turn on a couple plugins from webpack to minify our code and stuff. It stands for production. So with that we can run, $npm run build:umd.min
>> Kent C. Dodds: And we can look at the minified code, [SOUND].
>> Kent C. Dodds: It's great.

>> Kent C. Dodds: So let me show you a little bit. The webpack API itself is Google-able, so that's why I'm not showing you as much about that. But let me kind of explain more conceptually what webpack is doing here cuz I think that is something that is less Google-able. So first what you see is runtime for webpack.

This is how webpack defines what's called the webpack require function. It replaces all of your required statements with webpack required statements. And so then in here we get our code, _uniqueRandomArray, and it replaced all of our imports and require statements. Actually what happens is Babel transpiles your import statements into CommonJS require statements and then hands that off to Webpack, and then Webpack turns those into Webpack require statements.

And so, we're now, webpack requiring everything that we need. And that is basically the whole mantra for us. But what webpack is also doing is it bundling our dependencies as well, so we can ship this as a standalone library. And so here we have this file, which is actually a unique random array.

And this is npm to the T right here. Unique random array isn't just this code, but it has a dependency itself and that's a module called uniqueRandom. That uniqueRandom is this module here. So, yeah, there's npm for ya. They like modularizing things into tiny little chunks. And incidentally, those are both by Sindre Sorhus, who does lots of that.

And then the JSON loader is responsible for this bit. So remember, this used to be a JSON file. The JSON loader just basically turns it into a JavaScript module by saying module exports equals and then whatever the JSON file was. That's how we can take all of this stuff, copy it, stick it right in our console and it works.

Any questions there? I'm not sure if I'm saying this name right, I'm sorry about that. But the question is, does the order of dev dependencies matter? Not at all. And in fact when you check out the next branch or any time you run npm install --save or save dev, any time npm does anything with your package JSON it's gonna reformat it and reorder everything.

So you don't need to worry about the order, just put it wherever. Like I said, most of the time you're just gonna be running npm install. Okay, cool, let me just make sure that I covered everything I wanted to cover. Right, one other thing that we're going to want to do is for our validate script now.

We're building three things, we're building a main umd and a umd min and we're going to add a build script that composes all of these things to run at the same time and in parallel. So, here we're going to say npm-run-all --parallel build: *, this is just part of the npm-run-all API.

It allows you to if your using this kind of convention with something and than colon and than some more stuff, than it will just allow you to say okay I want you to run everything under build. Almost like it's a child of the build script, so than it'll run all three of these in parallel.

And now with our validate script running test, lint, builds, main, build:umd, and build:umd.min. And with that your validate script. Here I'm actually gonna time it, npm run validate. It will take a moment. So taking me three seconds, three and a half seconds, that is, fairly typical even for a smaller library.

Likely you'll only run this when you commit and I don't think three seconds is crazy long or anything. If you think it's long than port requests are welcome. I'm sure people would love to have you speed their stuff up.

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