nodeJS
关于node.js
node.js可以理解成JavaScript在服务器上面的运行环境
我们之前学习的JavaScript都有这么一个概念,JavaScript是运行在浏览器上面的,它必须依托网页html存在,没有网页的存在就没有它,但是后期人们将JavaScript运行在浏览器上面的chrome v8移植到了服务器端,这样就可以保证我们js代码能够在服务器运行,而不需要依赖浏览器和网页了
node.js它只是一个平台,不关于任何标准,只要是JavaScript语言就可以在上面运行
为什么前端要学node.js
按照常规开发思维来讲,前端是不需要学习后台的具体知识,只需要掌握一些基本后端原理就行,但是现在的主流开发模式已经趋向于前后端分离开发,在这种模式下,后端不需要负责前端的事情,但是前端却要掌握一些后端的知识,比如SQL语句,一些简单的数据库设计,http请求原理等等…
在以前,我们后端知识都是以php为主来学习的,但是php毕竟是一个独立后端编程语言,学习成本比较高,所以我们当node出现的时候,我们就选择了用node来替代php
node.js具备的先天性优势:
1、非阻塞的io
2、使用事件驱动
3、天生的高并发处理能力
4、单线程运行
node里面只有ES,没有DOM和BOM
nodeJS基础
当我们安装好了之后,我们可以在终端种输入命令node -v查看,如果显示了版本号就说明安装成功了
安装成功之后,我们如果想运行一个node.js,非常简单,执行一个命令
node 文件名.js
在node.js种不能运行DOM和BOM,只能运行ECMAScript
window.alert("a"); //报错,因为window是BOM里面的对象,不能在node里面使用
CommonJS模块化
在之前我们的学习的ES6中,使用的是ESModule的模块化规范,这是ES的通用规范,基本90%的js都是遵循这个规范的,但是我们学习的node不是的,它执行的是CommonJS规范
模块化开发的现在标准:
1、浏览器及ECMA执行的通用规范 ESModule
2、node.js平台使用的CommonJS
规范 | 导入 | 导出 |
---|---|---|
ESModule | import | export default |
CommonJS | require() | module.exports |
现在我们看一下代码:
Person.js
class Person{
constructor(userName,sex){
this.userName = userName;
this.sex = sex;
}
sayHello(){
console.log(`大家好,我叫${this.userName},我的性别是${this.sex}`);
}
}
//export default Person
module.exports = Person;
Student.js
const Person = require("./Person.js");
class Student extends Person{
constructor(userName,sex,age){
super(userName,sex);
this.age = age;
}
}
let s1 = new Student("张三","男",20);
s1.sayHello();
当我们 执行 node Student.js
就可以正确执行
CommonJS的模块导入
现在我们来研究一下
a.js
console.log("我是a文件");
b.js
console.log("我是b文件");
require("./a.js");
require("./a.js");
require("./a.js");
require("./a.js");
require("./a.js");
require("./a.js");
当我们导入多次的时候,我们发现最终a.js的代码只执行了一次
require方法导入一个模块之后,它会把这个模块缓存下来,下次再去导入的时候,则直接从缓存里面拿 ,在上面的代码里面,表面看起来是导入了6次,但是实际上只有第一次的导入是真的导入了,剩下5次都是从缓存里面拿的
CommonJS的缓存
如果我们希望某一个模块不放在缓存里面,我们可以在这个模块的后面添加以下代码
delete require.cache[module.filename];
这个时候再去执行就是导入了6次
CommonJS的模块导出
导入与导出应该是一对,所以在nodejs中如果导出我们可以使用以下两种方式
1、module.exports 直接导出
2、exports 指针导出
a.js
let userName = 123;
module.exports = userName;
b.js
const userName = require("./a.js");
console.log(userName);
完成了一个基本的导入导出
在CommonJS的模块化规范当中,每个文件都会有个专门用于导出的属性叫做 module.exports
,我们在require中实际导入的是 module.exports
当中的东西
module.exports
在每个文件里面,都有一个负责导出的对象,这个对象叫做 module.exports
如果我们直接打印这个对象我们会看到一个空对象 {}
let userName = "张三";
let sex = "男";
let obj = {
userName,
sex
}
module.exports = obj;
如果我们需要同时导出多个变量,我们可以把这些变量封装成对象,然后导出
还有这种情况
const obj = require("./a.js");
//或者
const {userName,sex} = require("./a.js"); //ES6解构方式导入
console.log(userName);
exports
在CommonJS的规范里面,真正负责导出的是module.exports,但是还有一个指针是指向了这个module.exports
console.log(module.exports === exports);
a.js
let userName = 123;
let age = 18;
module.exports = userName;
exports = age;
b.js
const obj = require("./a.js");
console.log(obj); //userName;
在上面的代码里卖弄,既有module.exports又有exports,那么b里面导入的到底是谁?
始终记住一句化,真正导出的是module.exports的东西,所以结果是userName
node平台的常用模块
nodejs它是一个运行平台,与浏览器一样用于运行js的,同理在nodejs上面,它会内置一些模块提供给我们使用
path模块
path模块是nodejs平台自带的模块化开发使用的一个模块,遵循的是CommonJS规范
console.log(__dirname); //代表当前js文件所属文件的所在目录路径
console.log(__filename); //代表当前js文件的路径
上面两个内置变量是nodejs平台上面最基本的点,也是经常会使用到的变量
其中对与路径这块,nodejs平台有专门的模块去处理,这个模块就是path模块,它不用下载,在安装nodejs里面就已经自带了
const path = require("path"); //导入nodejs的path模块用于处理路径问题
1、path.join()
把路径链接起来
let p1 = path.join(__dirname,"/txt");
console.log(p1);
2、path.extname()
获取某个路径的后缀名
let p1 = path.extname(__filename);
console.log(p1);
let p2 = path.join(__dirname,"/txt/abc.txt");
let p3 = path.extname(p2);
console.log(p3);
这个方法可以帮助我们判断文件的类型,方便我们以后是express框架里面做文件上传的时候判断文件类型
3、path.isAbsolute()
判断当前路径是否是绝对路径
let p1 = path.isAbsolute(__dirname);
console.log(p1);
这个方法的优点在于后面文件上传的时候,我们可以储存一个文件的真实路径
4、path.resolve()
将相对路径转换成绝对路径
let p1 = path.resolve("/txt/abc.txt");
console.log(p1);
FS模块
一般有了路径之后就会有文件,我们可以通过某一个路径去找到某一个文件
在nodejs当中,有一个专门用来读写文件的模块就是FS模块(file system)
1、fs.existsSync()
判断一个路径是否真实存在,可以判断文件夹路径,也可以判断文件路径
let p1 = path.join(__dirname,"/txt/abc.txt");
let result = fs.existsSync(p1);
console.log(result);
let p2 = path.join(__dirname,"/img");
let result2 = fs.existsSync(p2);
console.log(result2);
2、fs.rmdirSync()
删除一个空文件夹
注意:这个方法只能删除空文件夹,如果文件夹里面有文件夹或文件,则删除失败
let p1 = path.join(__dirname,"/img");
let result = fs.existsSync(p1);
if(result){
fs.rmdirSync(p1);
}else{
console.log("这个文件夹路径不存在");
}
3、fs.unlinkSync()
根据路径删除文件
let p1 = path.join(__dirname,"/txt/abc.txt");
let result = fs.existsSync(p1);
if(result){
fs.unlinkSync(p1);
}else{
console.log("这个文件不存在")
}
4、fs.copyFileSync(oldpath,newpath)
复制文件
let oldPath = path.join(__dirname,"/txt/abc.txt");
let newPath = path.join(__dirname,"/img/abc.txt");
fs.copyFileSync(oldPath,newPath);
5、fs.renameSync(oldpath,newpath)
文件重命名
注意:文件重命名的时候,一定要检测旧的路径是否存在,避免报错
let oldPath = path.join(__dirname,"/txt/abc.txt");
let newPath = path.join(__dirname,"/txt/hahaha.txt");
fs.renameSync(oldPath,newPath);
6、fs.mkdirSync()
根据路径创建一个文件夹
let p1 = path.join(__dirname,"/css");
let result = fs.existsSync(p1);
if(!result){
fs.mkdirSync(p1);
}else{
console.log("当前路径已经存在")
}
7、fs.readdirSync()
读取某一个路径下的文件夹的内部信息
let arr = fs.readdirSync(__dirname + "/txt");
console.log(arr);
这里的内部信息指的是该文件夹内的文件夹与文件信息(文件名)
应用:我们现在要获取到文件夹内部的信息,然后把文件夹内的txt文件删除掉,怎么做?
for(let item of arr){
//第一步:把路径拼出来
let tempPath = path.join(__dirname + "/txt",item);
//第二步:把路径的后缀名拿出来进行判断看是不是txt
if(path.extname(tempPath) == ".txt"){
fs.unlinkSync(tempPath);
}else{
console.log("当前文件夹内没有txt文件");
}
}
8、fs.statSync()
读取路径状态
let p1 = path.join(__dirname,"img");
let sta = fs.statSync(p1);
console.log(sta);
会打印
Stats {
dev: 509938464,
mode: 16822,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 1125899906976857,
size: 0,
blocks: 0,
atimeMs: 1664250327041.3667,
mtimeMs: 1664248502908.9805,
ctimeMs: 1664248502908.9805,
birthtimeMs: 1664248425771.7454,
atime: 2022-09-27T03:45:27.041Z,
mtime: 2022-09-27T03:15:02.909Z,
ctime: 2022-09-27T03:15:02.909Z,
birthtime: 2022-09-27T03:13:45.772Z
}
在上面弄得文件信息对象当中,有方法可以判断当前路径指向的是文件夹还是文件
sta.isFile() //判断当前路径是否是一个文件
sta.isDirectory() //判断当前路径是否是一个文件夹
练习案例
现在有了这个判断之后,我们可以在一个文件夹下面删除文件或者文件夹了
//txt目录下有文件夹和文件,如果我要把下面的内容都删除了,怎么办?
//第一步:设置路径
let p1 = path.join(__dirname,"/txt");
//第二步:判断文件夹路径是否存在
let result = fs.existsSync(p1);
if(result){
//第三步:读取文件夹内部的信息
let info = fs.readdirSync(p1);
//第四步:遍历里面的信息
for(let item of info){
//第五步:拼接txt文件夹内的路径
let tempPath = path.join(p1,item);
//第六步:读取这个路径的状态,判断是文件还是文件夹
let status = fs.statSync(tempPath);
//第七步:开始判断文件夹还是文件,根据类型使用对饮的删除方法
if(status.isDirectory()){
fs.rmdirSync(tempPath);
}else if(status.isFile()){
fs.unlinkSync(tempPath);
}
}
}
9、fs.readFileSync()
通过路径读取一个文件的内容
let p1 = path.join(__dirname,"/txt/aaa.txt");
let result = fs.readFileSync(p1,{encoding:"utf8"});
console.log(result);
10、fs.writeFileSync()
把内容写入到一个文件里面
let p1 = path.join(__dirname,"/txt/aaa.txt");
let str = `今天中午没吃饭`;
fs.writeFileSync(p1,str,{encoding:"utf8"});
OS模块
os模块主要是用于获取当前操作系统的相关信息
os.freemem()
获取当前电脑的空闲内容
os.totalmem()
获取当前电脑的总内容
os.cpus()
获取当前电脑的cpu信息,它返回的是一个集合
os.networkInterfaces()
获取当前电脑的ip地址信息
os.platform()
获取当前电脑的平台信息
os.hostname()
获取当前电脑的主机名
os.homedir()
获取到当前电脑的主目录
os.tmpdir()
获取当前系统的临时目录