1. node的安装和版本工具
- window选择.msi安装包
- Mac上的homebrew,Linux上的yum、dnf等
- 推荐安装14.17以上版本
版本管理
这里mac推荐使用版本管理工具 n
- 安装 n
npm install -g n
# 查看安装的版本表示安装成功
n --version
- 安装最新的lts版本
权限问题需要添加 sudo
# 安装最新的lts版本
n lts
# 安装最新的版本
n latest
# 查看所有的版本
n
windows系统上使用nvm-windows
下载链接:https://github.com/coreybutler/nvm-windows
安装指定版本, 基本使用命令
# 查看可用版本
nvm list available
# 安装指定版本
nvm install 14.13.1
# 安装最新的lts版本(若不可用则安装指定版本方式安装)
nvm install lts
# 安装最新的版本
nvm install latest
# 可设置nvm淘宝镜像
nvm node_mirror https://npm.taobao.org/mirrors/node/
nvm npm_mirror https://npm.taobao.org/mirrors/npm/
node的全局对象
- 特殊的全局对象
在模块中任意使用,但在命令行交互中不能使用
包括:__dirname、__filename、exports、module、require()
__dirname:获取当前文件所指的路径(不包括后面的文件名)
__filename:获取当前文件所在的路径和文件名称 - 常见的全局对象
- process对象:提供了Node进程中的相关的信息
- console对象:输出日志
- 定时器函数
setTimeout(callback, delay[, ...args])
setInterval(callback, delay[, ...args])
setImmediate(callback[, ...args])
回调事件“立即”执行
process.nextTick(callback[, ...args])
添加到下一次tick队列中
node 内置模块
1. 内置模块path
- 从路径中获取信息
const path = require('path');
const filepath = "/User/admin/abc.txt";
// 获取文件的父文件夹
console.log(path.dirname(filepath)); // /User/admin
// 获取文件名
console.log(path.basename(filepath)); // abx.txt
// 获取文件扩展名
console.log(path.extname(filepath)); // .txt
- 路径的拼接
join
相当于字符串的拼接
const path = require('path');
const basepath = "/User/admin";
const filename ="abc.txt";
// 路径的拼接
const filepath = path.join(basepath, filename);
console.log(filepath); // /User/admin/abc.txt
resolve
路径拼接
const path = require('path');
const basePath = '/User/admin';
const filename = 'abc.txt';
const filepath = path.resolve(basePath, filename);
console.log(filepath); // /User/admin/abc.txt
与join
拼接的区别
- resolve函数会判断我们拼接的路径前面是否有
/
或../
或./
; - 如果有表示是一个绝对路径,会返回对应的拼接路径;
- 如果没有,那么会和当前执行文件所在的文件夹进行路径的拼接
- join 相当于字符串的拼接
2. 内置模块 fs
- 获取一个文件的状态
const fs = require("fs/promises");
const filepath = "./abc.txt";
fs.stat(filepath).then(res => {
console.log(res.isDirectory());
}).catch(e => {
console.error(e)
})
- 文件描述符
- fs.open() 方法用于分配新的文件描述符。
- 一旦被分配,则文件描述符可用于从文件读取数 据、向文件写入数据、或请求关于文件的信息。
- 文件的读写
- fs.readFile(path[, options], callback):读取文件的内容;
- fs.writeFile(file, data[, options], callback):在文件中写入内容;
- 使用fs.mkdir()或fs.mkdirSync()创建一个新文件夹
option参数:
- flag:写入的方式。取值:
w 打开文件写入,默认值;
w+打开文件进行读写,如果不存在则创建文件;
r+ 打开文件进行读写,如果不存在那么抛出异常;
r打开文件读取,读取时的默认值;
a打开要写入的文件,将流放在文件末尾。如果不存在则创建文件;
a+打开文件以进行读写,将流放在文件末尾。如果不存在则创建文件- encoding:字符的编码;基本用的都是UTF-8编码。
const fs = require("fs/promises");
const filepath = "./abc.txt";
// 1. 写文件
fs.writeFile(filepath, "world", {flag: "a"}).then(res => {
console.log(res); // 返回null 表示写入成功
}).catch(console.error)
// 2. 文件读取
fs.readFile(filepath).then(res => {
// 不传 encoding ,会返回 Buffer
console.log(res)
})
fs.readFile(filepath, { encoding: 'utf-8' }).then(res => {
console.log(res)
})
// 3. 创建文件夹
const dirname = "./test";
fs.mkdir(dirname).then((result) => {
// 创建成功返回 undefined
console.log(result);
}).catch((err) => {
// 目录已存在,返回 {code: 'EEXIST'}
console.log(err);
});
// 4. 读取目录下的文件
fs.readdir(dirname).then((result) => {
// [ 'xxx.txt' ]
console.log(result);
}).catch((err) => {
console.error(err);
});
// 递归获取目录下的子目录的文件
function getFiles(dirname) {
fs.readdir(dirname, { withFileTypes: true }).then(files => {
for(let file of files) {
if(file.isDirectory()) {
const filepath = path.resolve(dirname, file.name);
getFiles(filepath)
}else{
console.log(file.name);
}
}
})
}
getFiles(dirname)
// 5. 重命名
fs.rename('./test', './foo').then((result) => {
console.log(result); // 成功返回undefined
}).catch((err) => {
console.error(err);
});
3. 内置模块 events
Node中的核心API都是基于异步事件驱动的:
- 在这个体系中,某些对象(发射器(Emitters))发出某一个事件;
- 我们可以监听这个事件(监听器 Listeners),并且传入的回 调函数,这个回调函数会在监听到事件时调用;
const EventEmitter = require('events');
const emitter = new EventEmitter();
emitter.on("click", args => {
console.log("监听1的click事件", args);
})
const listener2 = args => {
console.log("监听2的click事件", args);
}
emitter.on("click", listener2);
setTimeout(() => {
emitter.emit("click", "hello", "world");
// 取消2的监听
emitter.off("click", listener2);
emitter.emit("click", "hello02", "world02")
}, 1000);
方法的补充
emitter.once(eventName, listener)
:事件监听一次emitter.prependListener()
:将监听事件添加到最前面emitter.prependOnceListener()
:将监听事件添加到最前面,但是只监听一次emitter.removeAllListeners([eventName])
:移除所有的监听器