Real-Time Web with Node.js Real-Time Web with Node.js

Creating NPM Modules

Kyle Simpson
You Don't Know JS
Check out a free preview of the full Real-Time Web with Node.js course:
The "Creating NPM Modules" Lesson is part of the full, Real-Time Web with Node.js course featured in this preview video. Here's what you'd learn in this lesson:

One method for distributing Node Modules is to publish them to npmjs.org. This site has tons of Node Modules that can be installed via the npm command-line tool. Kyle demonstrates how to package and distribute a Node module using NPM.

Get Unlimited Access Now

Transcript from the "Creating NPM Modules" Lesson

[00:00:00]
>> [MUSIC]

[00:00:04]
>> Kyle: So that's it for 2.js.
>> Kyle: Let's go ahead and create 3.js and helloworld3.js. So same thing, do a save as.
>> Kyle: Helloworld3.js. And a save as 3.js. Okay, now update your 3.js so that you don't get yourself confused. Make sure it says 3.js. Make sure you're loading the helloworld3 module.

[00:00:38] Now before we do anything else with the hello3 module, we're gonna modify it. But before we do anything else, I want to talk to you a little bit about, a little bit about the ecosystem around modules, okay? Cuz we've already talked about the idea that I could do NPM install and bring in somebody else's module, like when you're in NPM installed my asequence library or when we brought in minimist or whatever.

[00:00:59] Where those things come from is there's a central repository called NPMJS.org. Central repository where people that create libraries for other people to use can publish their libraries to. And every time I make an update, I publish a new version of my asequence library up to the NPM repository and that NPM command line tool is configured to go find the latest version of it, and pull that down.

[00:01:23] So any time I make an update, the next time somebody asks for it, they'll get the updated version. And of course it installs the files in the correct location. What if we wanted to turn our helloworld into a package that we could publish to NPM? What would be the requisite steps?

[00:01:41] Okay, now we're not actually going to publish because our helloworld module the way we've named it if you will. Our helloworld module is a, [COUGH] excuse me, is that name is already taken. [LAUGH] There's already a helloworld module on npm. So we won't to actually do the final step which is npm publish to push, but I'll give you a sense of what the setup steps are so that you understand if you created yourself a little utility and you wanted to make it available for others or even if you didn't care that nobody else used it.

[00:02:11] You just wanted it up in a repose so that it was easy for you to deploy yourself to your own services. You can push it up into the npm refill. Of course, the more social you are, the more you let other people use it, the better the the ecosystem is.

[00:02:25] But what would it take for us to make this helloworld? We don't need to make any changes to the internal contents of it, because it's a functional thing. It may not be quite the right way that you wanna provide it yet, so we could make updates, but what we really need to do is configuration outside of our file, okay?

[00:02:40] So in that same directory, wherever we're gonna store our file that we're gonna turn into a module, we need to create a package.json file that describes what our module is. And we need that package.json file to be in the root of our npm package. In this case, it's my same exercises directory but you would probably do something like mkdir helloworld and have your whole helloworld module in its own subdirectory, most likely.

[00:03:10] For our simplification purposes, we're just gonna leave it all in this main directory, okay? So what we really need is we need a package.json file. Now I'm gonna cheat cuz I don't like remembering the syntax of package.json's but there's utilities out there. Npm has an init, there's an npm init that will build them for you and there's websites that will build them.

[00:03:29] I'm just gonna pull in the one that I've already created in the solutions directory here and you can do the same if you want to but I want us to look at that package file and understand what it does.
>> Kyle: So you can either pull it in or you can create this new from scratch yourself, but it's a JSON file.

[00:03:47] So it needs to be valid JSON syntax, all the keys need to be surrounded with quotes and we have string values and arrays. But let's point out a couple of important things, very important characteristics. This is kind of like almost the bare minimum that you'd have to have, to have a valid package JSON.

[00:04:05] We need to give it a name property and that name is really important because that name is the unique identifier for that module in the npm registry. Which means you have to pick a name that nobody else's picked. If you try to override it then there's going to be collisions and it's not going to work.

[00:04:21] So I couldn't actually publish this one because there is already one called helloworld. If I were to make it like helloworld3 there's maybe a chance that I could publish it. But, we're not going to do that. So, I've got "helloworld", is my name. The next most important field is the version number, because you have to manually version your modules, an npm uses what's called sim-verse, semantic versioning.

[00:04:45] So, the traditional way that you see people dealing with semantic versioning is that there's a major, and a minor version. And, then this patch version. And, then optionally you can have this fourth level, if there's trivial updates that you're making. Usually, I use those if I update the documentation for a project.

[00:05:05] I haven't changed anything about its functionality but I've updated the documentation. So I bump it from a to b, or b to c. Sometimes if I make a little minor bug fix that nobody worries about or a typo fix or something, I'll bump those. But most of the time if you make a functional change to your code you would bump the patch version from 0.0.1 to 0.0.2 for instance, okay?

[00:05:28] Now, the versions are really, really important, because they need to be strictly ascending, which means you need to make sure that you're always bumping it up rather than bumping it down. And also, once you publish that version, like if we were to publish 0, 01A, we can never ever publish this same name and version again.

[00:05:49] So if we wanna update it, we have to bump the version. We have to at least bump it to -B or 0.02 or something. They don't allow you to overwrite an existing version of a module anymore. He used to be able to do a force and they just recently did away with that.

[00:06:06] So now You have to bump the version if you want to do it. Now, I'll leave you as a sort of a homework for you to read more about read about SemVer, read about semantic versioning, the npm website has a help item all about semantic versioning. But the basic idea is that you don't make any breaking API changes in your patch versions.

[00:06:30] And if you make breaking API changes, you would bump at least the minor version, if not the major version. Major versions are usually a complete rewrite, or a whole new set of features, or a whole new way of doing things. So, you don't bump those very often. That's just the typical kind of guideline, or the philosophic guideline for it.

[00:06:49] There's a lot of gray area in terms of when should I bump the minor or the patch or whatever. Everybody has different opinions on it but there's a bunch of reading that you can do about SemVer, if you're interested. Now the description field not technically required, but it's a good idea to go and put a description field cuz otherwise nobody's gonna know what it does.

[00:07:07] The next most important one is this main key on line five. We have to tell it what is our main entry point file in our module sub directory. Now in this case, I just have one file it's the helloworld3.js. But most of the time you have non-trivial modules that may have dozens of files in a lib directory and you may build things and put different versions of it you need to have a main entry point that when they use your module and they do a require and they use the name of your module, this is the file that it's gonna pull in.

[00:07:45] Yeah.
>> Speaker 2: There is a question online maybe some material they want to have some text highlighter you're using your JSON there.
>> Kyle: So this is the sublime text editor. Sublime doesn't come with a very good JSON coloration in it, so I did a custom color configuration for JSON.

[00:08:05]
>> Speaker 2: So you rolled it yourself?
>> Kyle: Yes, but I didn't roll my own syntax highlighter, I rolled my own color theme for JSON, because the color scheme that I'm using by default didn't have a good one.
>> Kyle: [COUGH] All right
>> Kyle: So that name is the main entry point and so that you have to decide where is the main entry point when somebody requires my file, what are they gonna be requiring in.

[00:08:35] Keywords not strictly necessary although it helps for your stuff to be found more, you should definitely put in an author and definitely put in a license attribute as well. Other keys that you can put in here that you're probably gonna want to put in if your module is stored up on GitHub, you're gonna wanna put in a key here for the repository and you can link it to your GitHub repository.

[00:08:58] You can link in information about where people should file bugs, you can link in information about dependencies. If your module requires other modules that wouldn't be built in, like if our module required minimist, which it doesn't cuz that's our main program but if we required minimist, then we would want to list the dependencies list.

[00:09:20] And the dependencies list,
>> Kyle: You would say something like minimist and then you have to tell it what version you want. So you got to know what version you're on. The easiest way to do that is to say node_modules/minimist and look at their package JSON to see what version.

[00:09:45] There's other npm command lines. So we're on point 0.0.8, right? Well, that means that I want at least point 0.0.8. But how do I decide? Do I only want that or what if they released an 0.0.9, would I want that? What if they released an 0.1 or a 1.0, would I want that?

[00:10:04] So the typical thing that people will do, you put a tilde here. And what that says is, I want all of the update, all of the patch updates, but I don't want any minor or major version updates because those might be API breaking changes. So I wanna manually decide that I need to up my dependency list, but if at some point he releases and 0.0.9 or an 0.0.10 or 11 or something, we're always doing is just making little patch bug fixes, then it's okay for you to go an update because I'm not worried about the API compatibility.

[00:10:38] So typically, people put that little tilde in front of it to say give me only the patch updates but not the major and minor version of things. So, that's how we'd list our dependencies. There's other keys in here and I'll leave it as your homework to kinda go and read about, but we need to construct ourselves a package JSON somewhat similar to this file and when we do an npm publish, it's gonna look for this file so it knows how to package it up knows what version to use and all that.

[00:11:04] So it's a required element here.