Node.js uses CommonJS as its module loader. Scott explains how to use the require() method to load built-in modules, Node.js modules, and user-created modules. He also talks about the differences between using exports and module.exports when creating a module.
And of course the modules that we make. So here's a little code snippet of how that actually works. So if we were inside of a node file, and I'll show you in a minute. I just do it from the Terminal. This is how we would get access to a built-in node module. We would just say var whatever you want to call it equals and then use the require function and then pass in the name of that module. And this specific example, the path module is a module that is built into Node. And if we get a little more fine detail, we know that this either a built-in node module or a module that we downloaded.
And that's because we didn't have to prefix it with a ./, and if you don't prefix your names in the require that means what happens is Node is automatically going to assume that it's either a built-in node module or its belonging in the node modules folder. If you put a ./ in front of it, it's going like oh this is a module that you made somewhere in this directory. Let me go find it. And I'll show you what that looks like in a minute. So this is an example of a built-in node module that we did not have to download. It's already baked in the node path.
Here's the example of the one that we downloaded. So this is like we npm install lodash, which is an alternative to underscore. If you've ever used UnderscoreJS, it's the same thing. And this is how we require. It's the same thing. We just require the name of the package, which is lodash. And we don't have to put a ./ in front of it because it's installed in node modules folder. So we don't have to do that. Anything that's in a node modules folder, you don't have to put ./ in front of it. But for this one, which is the module that we created in a separate file, we have to put ./ in front of it.
It might be Jason or something else, but by default it's going to be JS. So you don't have to put the extension. If you do put the extension, it's not going to break. But you don't have to. Any questions on that stuff? Okay, so above are examples on how to access node modules using CommonJS. So this is how we would access them. Here are some examples of how we would expose them if we were to create them. So these are like two different files. But here's the one file.
So we would use the... Oops. It should be exports, not export. I forgot to put the s there. So we would use the exports keyword here, which would allow us to expose. Yes. - [Man] There's a question, how does Node know where the node modules folder is? - Uh, the node modules folder will always be on the root of the application, next to npm. And if it's not there, it will recursively look for it. - [Man] I guess a follow up to that is, yeah.
How does Node know where the project road is? - How does Node know where the, ah good question. Yeah so, so I'll get to that. I have an example for that. So yeah we'll use the exports, which just came out of nowhere. So in Node there does exist this type of things like globals, kind of like in the client where you have everything attached to the window, or everything in some type of global space. There does exist some concept of that in Node, and that's because in Node actually what's happening is when you make a file in Node, it's actually wrapped in an iffy.
So, it doesn't matter what file you do, this is what Node does when it executes your file. So your actual code would be inbetween here, and what the node does is it gives you some globals. Something like module. It also gives you exports. It gives you, like, dirname, which is the directory name that it's in. All that stuff like that, so. And now you have access to those variables inside your code, which will be in here.
So every file is wrapped in one of these. It's held in closure. So if you want to see what that looks like, it's literally in the source code. You can go check it out. It's exactly how it is. So there's a couple other things in here like, there's a few other things in here, so yeah. So that's how we get access to exports and module.exports and dirname and all that global stuff because it's attached that way. So using the exports keyword, we're able to export individual things. Just attach it to the exports object and then now we can require it.
Should be exports, not export. And alternatively we can also do module.exports, which is just like I'm just going to expose this one module here. Exports is like, exports is an object that we can attach different pieces of our code to. Module.exports is the entire object. And we're defining it differently. So it's kind of the same thing. Whereas like exports we're like let's put a setup function here and an enable function here, a ready function here.
It's the same thing if we said module.exports, which is an object, and then putting all these (speaker drowned out by interference) on it. So you can use whichever syntax you want. They both kind of do the same thing. Any questions on that? Okay. So, using exports object on a module we can expose our code to be required later.
- [Man] There did pop a question here. Do you think Node will support ES6 style modules in addition or replacing CommonJS style modules? - Um, that's a good question. I don't know, well I mean they're using V8 internally, so when V8 keeps getting updated, so that's actually like a really debatable question because Node and IOJS, it's this big divergence between of Node and a different version of Node. A group of people forked Node and made something called IOJS because they were tired of Node not being updated readily, and not keeping up with security updates of V8.
So IOJS made it their practice to keep everything new and start implementing ES 2015 features, and then now there's news of IOJS being merged back into Node. Some of those features are coming along. Actually in Node version 12, if you used strict, you actually get some ES 2015 features but not all of them. So because of that, I would say yeah they will probably support the ES 2015 modules because they're already showing support for the ES 2015 features that exist today. So when that's going to happen, not sure.
They might have a roadmap for it. But yeah, they definitely will get there if they get to rely on V8. - [Man] A couple more popping in here. What are the pros and cons of module.exports versus exports? - Yup, so module.exports once you do that you cannot export anything else, so once you do a module that exports you cannot in that same file do exports.this, that's it. Module.exports is the only things that's going to be exported. Using exports just means that when you require it and the next file, let's say we export it, a lot of stuff on this module, then this variable myModule will always be an object because exports is an object.
So if we say exports.setup, exports.enable, exports.ready and then we just require this file config.js, this myModule will be an object that has a .setup property, a .enable property, a .ready property, whereas if we use like module.exports, we can set this file to be whatever we want. So we don't have to put an object here. We can say we'll let's just put the number three. And then when we require it, this value will be three. So, using exports you always be an object when you require it.
Using module.exports, it'll be whatever you export on module.exports. - [Man] Can you assign a single value to module.exports? - Yup, you can put any value you want except for, you can't say module.exports equals exports, or I mean you can't say module.exports equals module.
Or I guess you could but you'd probably have some side effects. But yeah, you can put whatever you want there.
This course was created by Frontend Masters. It was originally released on 12/30/2015. We're pleased to host this training in our library.
- Executing Node.js
- Using Express
- What is middleware?
- Testing in Node.js
- Using Mongo with Node.js
- Data modeling
- Querying data with Mongoose
- Identifying sensitive routes
- Configuring the deployment