相关网址:https://nodejs.org
Node.js是一个开源与跨平台的JavaScript运行时环境,它是在浏览器外运行,他是一个事件驱动异步I/O单进程的服务器JS环境,基于Google的V8引擎,V8引擎执行javascript的速度非常快,性能非常好。它使用新的ECMAScript标准,不必等待所有用户更新其浏览器,可以通过更改其版本来决定要使用新的标准特性。
注意:
nodejs环境安装非常便捷,直接可通过官网地址,下载对应的安装软件包即可安装使用、
注:尽量下载长期支持版本(LTS),如果在工作中有多个node环境的切换,可以安装ndoe环境管理工具NVM:https://github.com/coreybutler/nvm-windows/releases
nvm可以让你的电脑中有N多个node版本。
NodeJs基于Commonjs模块化开发的规范,它定义一个js文件就称之为一个模块。
node的模块类型:
自定义模块并导出
在模块包中定义一个package.json文件,并指定入口文件
在应用代码中导入并使用
5.1、命令参数
在通过node命令执行js文件时,有时为了业务需要,可能要在执行的命令中添加参数来实现相对应的业务。
node app.js --port 3000
此时可以通过 process 此内置对象来完成参数数据的获取。
//在应用文件中通过process.argv程序来获取命令中参数
let args = process.argv.slice(2).reduce((p, c, index, arr) => {
if (c.startsWith('--')) {
p[c.slice(2)] = arr[index + 1]
}
return p
}, {})
console.log(args);
======================================
//使用minimist第三方插件快速获取参数数据
//下载minimist npm i -S minimist
const minimist = require('minimist')
console.log(minimist(process.argv.slice(2)))
在程序开发中,环境都是有开发环境和生产环境之分,如果以最少的代码改动完成开发与生产环境的区分呢?多数情况下,我们都是通过环境变量的方式来完成此项需求。
cross-env是什么:运行跨平台设置和使用环境变量的脚本 。
安装cross-env插件
npm i cross-env -D
os模块提供了与操作系统相关的实用方法和属性。
const os = require('os')
// 换行符
os.EOL 根据操作系统生成对应的换行符 window \r\n,linux下面 \n
// 查看cpu相关信息
os.cpus()
// 总内存大小 (单位 字节)
os.totalmem()
// 空余内存大小 (单位 字节)
os.freemem()
path模块用于处理文件和目录(文件夹)的路径。
//获取路径最后一部内容 一般用它来获取文件名称
path.basename('c:/a/b/c/d.html') // d.html
// 获取目录名,路径最后分隔符部分被忽略
path.dirname('c:/a/b/c/d.html') // c:/a/b/c
// 获取路径中文件扩展名
path.extname('c:/a/b/c/d.html') // .html
// 给定的路径连接在一起
path.join('/a', 'b', 'c') // /a/b/c
// 把相对地址转为绝对路径
path.resolve('/a', '../b')
URL字符串是结构化的字符串,包含多个含义不同的组成部分。 解析字符串后返回的 URL 对象,每个属性对应字符串的各个组成部分。
使用js提供的URL类完成url参数分析
fs模块提供了用于与文件进行交互相关方法
buffer是一个容器(缓冲器)一般用来存储数据流
文件操作
const fs = require(‘fs’)
写入数据
fs.writeFile(文件路径,数据,err=>{})
读取文件中数据
fs.readFile(文件, 'utf8’,(err,data)=>{})
检查文件或目录是否存在 返回true/false
fs.existsSync(path)
获取文件信息
fs.stat(文件,(err,stats)=>{
stats.isDirectory() // 是否是目录
stats.isFile() // 是否为文件
stats.size // 文件大小(以字节为单位)
})
删除文件
fs.unlink(文件,err=>{})
目录操作
创建目录
fs.mkdir(‘./logs’, { recursive: true }, (err) => {
console.log(‘done.’)
})
删除目录
fs.rmdir(‘./logs’, { recursive: true }, () => {
console.log(‘done.’)
})
读取目录列表
fs.readdir(path, (err,data) => {
// data是一个数组,里面包含了当前路径下所有的文件和文件夹名称
})
// 文件操作
const fs = require('fs')
const pfs = fs.promises
const path = require('path')
const os = require('os')
// const util = require('util')
// const readFile = util.promisify(fs.readFile)
// 创建一个文件
// const str = '你好!!aaa' + os.EOL;
// 字符串转为buffer流
// console.log(Buffer.from(str));
// 异步
// 回调函数中的参数,如果返回为null则表示,成功,为对象表示写入异常
// fs.writeFile(path.resolve('data/lisi.txt'), Buffer.from(str), err => console.log(err))
// fs.writeFile(path.resolve('data/lisi.txt'), str, err => console.log(err))
// 同步
/* try {
fs.writeFileSync(path.resolve('data/lisi.txt'), str)
} catch (e) { }
*/
/* fs.writeFile(path.resolve('data/lisi.txt'), str, {
encoding: 'utf-8',
// 在linux和mac下有效果 权限有关,一般不设置 777 rwx 421
// 第1个7 当前文件所属用户
// 第2个7 当前文件所属的组
// 第3个7 其它用户
// mode:
// w 写且覆盖
// flag: 'w'
// a 写且追加
flag: 'a'
}, err => console.log(err))
*/
// fs.appendFile(path.resolve('data/lisi.txt'), str, e => console.log(e))
// 读文件
let filepath = path.resolve('data/lisi.txt');
let newfilepath = path.resolve('data/lisi-bak.txt');
// nodejs回调参数 第1个都是错误参数
/* fs.readFile(filepath, (err, buffer) => {
console.log(buffer.toString());
}) */
/* fs.readFile(filepath, 'utf-8', (err, data) => {
console.log(data);
}) */
/* let data = fs.readFileSync(filepath, 'utf-8');
console.log(data); */
/* fs.readFile(filepath, 'utf-8', (err, data) => {
fs.writeFile(newfilepath, data, err => console.log(err))
})
*/
// readFile(filepath).then(data => console.log(data.toString()))
// readFile(filepath).then(data => console.log(data))
/* ; (async function () {
let data = await readFile(filepath)
console.log(data);
})() */
// 复制文件
// pfs.readFile(filepath).then(data => pfs.writeFile(newfilepath, data))
// 数据流 管道
// 读流 fs.createReadStream
// 写流 fs.createWriteStream
// fs.createReadStream(filepath).pipe(fs.createWriteStream(newfilepath))
// 删除文件 和操作系统相关,有的时候,可能删除不掉,此时就需要在操作系统层面去解决
// sudo chmod -R 777 data
// fs.unlink(newfilepath, err => console.log(err))
// 查看文件信息
/* fs.stat(filepath, (err, stat) => {
console.log(stat.isFile()); // 判断是否为文件 true
console.log(stat.isDirectory()); // 判断是否为目录(文件夹) true
}) */
// 判断当前文件或目录是否存在
// console.log(fs.existsSync(filepath))
// ======================= 目录
// f:\www\clas\nodejs\data\admin\bb\cc
const dirpath = path.join(__dirname, 'data', 'admin')
// 创建目录
// fs.mkdir(dirpath, err => console.log(err))
// 迭代创建
// fs.mkdir(dirpath, { recursive: true }, err => console.log(err))
// 读目录 返回是一个数组
/* fs.readdir(dirpath, 'utf-8', (err, data) => {
console.log(data);
}) */
// 删除 rmdir默认只能删除空目录
// fs.rmdir(dirpath, err => { console.log(err); })
// 递归删除
// fs.rmdir(dirpath, { recursive: true }, err => { console.log(err); })
delDir(dirpath, () => { })
function delDir(dirpath, cb) {
fs.stat(dirpath, (err, stat) => {
if (stat.isFile()) {
fs.unlink(dirpath, cb)
} else {
fs.readdir(dirpath, 'utf-8', (err, dirs) => {
if (dirs.length == 0) {
// 此目录是一个空目录
fs.rmdir(dirpath, cb)
} else {
// 读取的目录中的相对路径转为绝对路径
dirs = dirs.map(item => path.join(dirpath, item))
let index = 0;
function doneFn() {
if (++index == dirs.length) {
fs.rmdir(dirpath, cb)
}
}
dirs.forEach(dir => {
delDir(dir, doneFn)
})
}
})
}
})
}
// 目录和文件都可以重命名
// fs.rename()
/* function readFile(filepath) {
return new Promise((resolve, reject) => {
fs.readFile(filepath, 'utf-8', (err, data) => {
if (!err) {
resolve(data)
} else {
reject(err)
}
})
})
}
*/
以流的方式逐行读取
const fs = require('fs')
const path = require('path')
// 逐行读取 以流的方式读取
const readline = require('readline')
// 日志路径
// const logpath = path.join(__dirname, 'data', 'access.log')
const logpath = path.join(__dirname,'data','access.log')
console.log(logpath);
// 此文件使用逐行读取方式读取
const line = readline.createInterface({
input: fs.createReadStream(logpath)
});
// 监听文件流到行尾时触发
line.on('line', data => {
console.log('aaa ---' +data);
})
Events模块是Node对“发布/订阅”模式(publish/subscribe)的实现,加载events模块后,通过EventEmitter属性建立了一个EventEmitter对象实例,这个实例就是消息中心,然后,通过on方法为事件指定回调函数,最后通过emit方法触发事件。
const EventEmitter = require('events')
const events = new EventEmitter();
// 订阅
events.on('上课了', arg => {
console.log('小明订阅:' + arg);
})
events.on('上课了', (arg) => {
console.log('小张订阅:' + arg);
})
##############
events.emit('上课了', '今天学习nodejs')