
Introduction to Node.js The fs Module
This course has been updated! We now recommend you take the Introduction to Node.js, v2 course.
Transcript from the "The fs Module" Lesson
[00:00:03]
>> Scott Moss: So we talked about modules that you created. Now, we're gonna talk about modules that come shipped with Node.js. I mean, I just call them shipped modules. You can call them internal modules. Don't call them Node modules, cuz there's another thing called Node modules. But technically, they are the modules that Node comes with.
[00:00:22] I'm just gonna say, shipped modules now, cuz they're shipped with them or whatever. But basically, Node ships with a bunch of helpful modules already. I'm just gonna talk about a few of them, so fs, which is short for file system, you use that for interacting with files on a machine, right?
[00:00:37] So I talked a little bit about fs before, but let me show you what I'm talking about. So I'm just gonna make a file. I don't wanna do this here, I wanna do it somewhere else. So,
>> Scott Moss: Yeah, let's do it here.
>> Scott Moss: All right, so check this out.
[00:00:53] So if I have, I got these two files, app and lib, I'm just gonna make another file. And I'm just gonna call this,
>> Scott Moss: Playground.
>> Scott Moss: Cool, so what I'm gonna do is I'm gonna require the internal module fs. But I only taught you how to require modules that you created.
[00:01:18] So how do you require and turn the modules? Well, there's no relative path because I mean, I don't see a module called fs anywhere. So how do I require that? Well, the way you do that is you just say require, use the same require function, but instead of doing something like relative because there is no relative path cuz it's internal, you just put the name of it like fs.
[00:01:39] That's it, that's the name of this module, it's called fs, short for file system. So if I don't put a dot, this is why I said the dot is very important on those internal modules, cuz that's telling Node that you're trying to require a module that you created, got it.
[00:01:51] If you don't do that, it's gonna think you're trying to require either an internal module or a remote module. So you have to use the dot for your modules and not the dot for internal or remote modules. So this is telling Node that this is either an internal module or it's a remote module.
[00:02:10] And remember, when I console that log, the module out earlier had those paths that was building up, and each one of them ended in Node modules? That's because Node is looking at all those folders for the module, it was looking for it until it can't find it, then it breaks.
[00:02:25] So it looks, it starts to the route that goes all the way up, and every single Node modules directory until it finds what you're asking for. And if it doesn't, it says, it doesn't exist, and also looks internally. So yeah, fs is short for file system, so that's internal, we'd have to install it, it's just shipped with Node.
[00:02:43] So the way that works is, there's just so many methods on here, I'm just gonna put dot. Look at all these methods on here. appendFile, appendFileSync, literally everything you could do with files is on here, and you could do all in JavaScript. So if you've ever like done any like bash scripting or stuff, you might be thinking like, okay, this is pretty dope.
[00:03:01] This is pretty dope, I can do some crazy stuff. Yeah, you can do some pretty crazy stuff with file systems in Node. I mean, yeah, pretty crazy stuff. I would say, some of the best tools I've ever seen in Node are just like hacks around the file system, like web pack.
[00:03:15] It's just like, ridiculous, it's basically a file system stuff. GOAP is another one. So file system stuff is really amazing. It's really great for helping developers automate things and scaffold out things, and just get the job done a lot faster. So some of the helpful methods are gonna be reading a file and writing to a file.
[00:03:33] So what I'm gonna do is I'm just gonna read a file. So I'm just gonna say, let's say, it's read the file, so let's say, fs.readFileSync. I'm gonna use sync for now, we're gonna talk async later, but I was gonna use everything sync for now. So you'll see that fs has a method, like readFile, and then have a sync version of it.
[00:03:53] We're just gonna use the sync version for now until we get to the async stuff, I promise we'll get there. And this thing's telling me like, you need a path. So you need a path here. What I wanna do is I wanna read this lib.js file. I wanna read that file and just print it out.
[00:04:09] So I might just do something like this, lib.js, right? It's a relative path, we'll see what happens. I'll tell it how to encode itself, which is just, I think this is even a default but I'm gonna be explicit about it which is utf-8, this is the encoding. If you ever done any advanced string stuff in software, you know there's different types of encodings for strings, this is it.
[00:04:31] But I think, it's utf-8 by default. If you don't know what that is, just always put utf-8 and you'll be fine. So this is gonna synchronously grab us the file, so I'm gonna say, file. I also gonna log the file and we'll see what happens. So if this works, I should expect to see, I'm gonna put toString here just in case it returns, it doesn't buffer.
[00:04:51] So if this works, I should expect to see lib.js printed out as a string, right?
>> Speaker 2: If you wanna console log file-
>> Scott Moss: Sorry, yeah, my bad. There we go. So if this works, we should see the file print out as a string. So what I would do is, let me cd test, and then node playground, all right?
[00:05:18] Look at that. So if we go look at lib.js, that's exactly what's there, right? So same thing. Any amount of time the difference between reading this file with the file system, and requiring it with the module system, what's the difference?
>> Speaker 2: Is it executed or not?
>> Scott Moss: Exactly, yeah.
[00:05:41] When I read it from the file system, it's just a string. It's literally just as string, it doesn't know any better. I just printed it out. When I required it and when I import it, it's like a code. It's been executed. It's real code that I can use, right?
[00:05:51] Everything is a memory. So that's the difference. You don't wanna use the file system to require a file that you plan on executing. I mean, you can use exec in JavaScript, but that's just not safe, so I would never recommend doing that. So yeah, that's where the require system comes in.
[00:06:09]
>> Speaker 3: What's the difference between reading a file, synchronous versus asynchronous, and when do you use?
>> Scott Moss: So I want to hold off on this and go dee into this later, but in short, the difference is exactly in the name. So synchronous means that whenever the file system returns the file or an error, whichever were to happen, it will assign it to this variable and then it will go to the next line.
[00:06:33] If it's asynchronous, this will fire, and then the next line will happen immediately. And then, when this is done, whether a promise or a callback, then it will respond to that layer. So it's just like, it's doing it in the background versus waiting to go to the next line to do it.
[00:06:46] It's just like the browser, if you did something asynchronous in a browser, or not the browser, there's no difference here. The only thing, and like I said, we'll get to this when we talk about async, is that like async is just way more important in Node, especially when you're building APIs, it's like detrimental to use everything async.
[00:07:01] If you don't, you can have some pretty bad problems. Whereas the browser, it doesn't really matter, at all.
>> Scott Moss: Cool, so that's like reading a file. Writing a file is kind of much the same thing. So I could just say, fs.writeFile, which, I'm just gonna write over the file that's there with .js.
[00:07:28] And I'm gonna put var me = me, and I'm just gonna do that. And we'll just run this again, and you could see, I didn't do sync. There we go, gotta use the sync, cool. Around that, and then we'll go look at lib, as you can see there, it has completely overwritten the file, var me = me.
[00:07:52] That's because write file just overwrite a file. If you wanted a append to it, you would use a append file, and then you would just like, add to it versus completely blowing out the file. So you can see, it's pretty powerful. You can do some pretty crazy stuff, so if you wanted something like rails that you might have used before, you could build those conventions with a file system, which tons of people do.
[00:08:09] Those tools are called scaffolding tools, or in today's world, they're CLIs, like a Vue CLI, or a React CLI, or an Angular CLI, or even Express has a CLI. There's so many CLIs. That's what these tools do. They just write to the file system to help you do things.
[00:08:23] Yes?
>> Speaker 4: So when you look, you use Angular CLI and you say generate component, then that's using Node to write those files.
>> Scott Moss: Yep, exactly.
>> Speaker 4: No more complicated than that?
>> Scott Moss: That's all it is. Yeah, it seemed magic. It's like, what are they doing? No, it's just that.
[00:08:37] They use a template, right? They do something like this, right? So they'll have, you might have a file. I can just show you a quick example of that like template.js. And they might have a file like this, const and then, this is not valid JavaScript. This will not work, right?
[00:08:53] So you might, I'm trying to give a good regex where I don't have to mess it up. You might have something like this, and it's just like some of our thing, and then you'll have some value that gets added here. This is not valid JavaScript. And what they'll do, or actually, they'll be like this, what they'll do is that they'll read this file in memory, right?
[00:09:19] So they'll do something like this, where they read the file, right? They'll get back a string that looks just like this, it's just a string, and then they'll use a regex or a template engine, so every time they see dot dot or the slash slash, or underscore underscore, they'll replace it with the object that you gave it, right?
[00:09:34] So if you have an object that has a bar property on it, and its value was hello, then now that's gonna be hello, all right. And if you had, and the object had a value, and its value was like cookies, then now, that's gonna be cookies. So it's just a template, that's what they do.
[00:09:56] So they have a component template that goes, this is what a base component looks like. And then, when you run the command, you might give it options, like the name of the component, maybe the path where to save it or whatever. And then, they just grab a template file that looks something like this, like a file that's not valid.
[00:10:12] They'll read it, and then they'll take the options that you gave it, mixed with their default options, and they'll output a valid file and save it. And then when it executes, it's good. So that's just like templating, yeah.
>> Scott Moss: Any questions on fs, file system? There's a lot more stuff to do in file system.
[00:10:31] A lot more nuances, a lot more crap that's very annoying, well, a lot more stuff that's really fun. So I definitely explore it, especially if you're gonna be doing some automation tools.