1. 运行环境
- Node v16.15.1
- VSCode 2022
2. 常用内置API
2.1 fs文件模块
读取文件,语法:
fs.readFile(path, encoding, callback(error, info)
参数说明:
- path ,读取文件所在路径
- encoding,读取文件的编码
- callback,读取文件后执行的回调
- error,若出错则为异常,否则为 null
- info 为读取的结果,若读取错误则为 undefined
【例1】读取文件
const fs = require('fs')
fs.readFile('./demo.txt', 'utf8', function(err, result){
if(err == null)
console.log('读取成功, result=', result)
else {
console.log('读取失败, result=', result)
}
})
写入文件语法:
fs.writeFile(file, data[, options], callback)
参数说明:
- file,必选,指定文件保存的路径
- data,必选,表示要写入的内容
- options,可选参数,表示以什么格式写入内容,默认为 utf8
- callback 必选,回调函数,文件写入后执行的回调函数
【例2】写入文件
const fs = require('fs')
// 定义要写入的内容
const user = {
name: 'uni',
age: '22'
}
fs.writeFile('./demo2.txt', JSON.stringify(user), function(err){
if(err == null)
console.log('保存成功')
else {
console.log('保存失败')
}
})
注:Node.js 支持 __dirname 获取当前 js 脚本的运行目录
console.log('目录:', __dirname)
2.2 path 路径模块
path 模块是 Node.js 官方提供的、用来处理路径的模块。
2.2.1 path.join 拼接字符串
path.join() 方法可以把多个路径片段拼接为完整的路径字符串
const path = require('path')
const pathstr = path.join('/a', '/b/c', '../', './d', 'e')
console.log(pathstr) // 拼接结果: \a\b\d\e
注:Node.js 中路径拼接的操作通常都是使用 path.join() 而不是使用加号直接拼接
2.2.2 path.basename() 获取文件名
path.basename() 方法可以获取路径中的最后一部分,这个方法经常用来获取路径中的文件名
const path = require('path')
const filePath = path.join(__dirname, 'demo.txt')
const fileName = path.basename(filePath)
console.log('文件路径: ', filePath)
console.log('文件名: ', fileName)
运行结果
文件路径: H:\javascript-demo\demo.txt
文件名: demo.txt
2.2.3 path.extname() 获取扩展名
path.extname()可获取路径中的文件拓展名,通常用来获取文件的类型
const path = require('path')
const filePath = path.join(__dirname, 'demo.txt')
const fileType = path.extname(filePath)
console.log('文件路径: ', filePath)
console.log('文件类型: ', fileType)
运行结果
文件路径: H:\javascript-demo\demo.txt
文件类型: .txt
2.3 http 模块
http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块
const http = require('http')
const server = http.createServer()
server.on('request', (req, res) => {
res.end('服务器已启动成功')
})
server.listen(8080, () => {
console.log('server running at http://127.0.0.1:8080')
})
【例】使用 Node.js 的 http模块 实现不同 URL 访问返回不同的 HTML 内容
const http = require('http')
const server = http.createServer()
server.on('request', (req, res) => {
// 获取请求的url地址
const url = req.url
console.log('请求地址:', req.url)
// 定义返回的 HTML 内容
let content = '<h1>404 Not found!</h1>'
// 根据请求的 URL 返回不同的 HTML 内容
if(url === '/' || url === '/index.html'){
content = '<h1>首页</h1>'
} else if(url === '/about.html'){
content = '<h1>关于页面</h1>'
}
// 设置响应头, 解决中文乱码问题
res.setHeader('Content-Type', 'text/html;charset=utf-8')
// 调用 end 方法,返回内容给客户端
res.end(content)
})
server.listen(8080, () => {
console.log('server running at http://127.0.0.1:8080')
})
3. 模块化编程
Node.js 根据模块来源不同,将模块分为三大类,分别是:
- 内置模块,例如 fs、path、http 等
- 自定义模块,用户创建的每个 .js 文件都属于自定义模块
- 第三方模块(由第三方开发出来的模块,使用前需使用 node install 命令下载)
Node.js 提供 require()方法来加载上述的模块,加载时可忽略 .js 文件后缀
模块作用域
和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域
module 对象
node.js 提供了 module 内置对象,我们可以直接访问,其内部存储了和当前js模块有关的信息
console.log(module)
运行结果
Module {
id: ‘.’,
path: ‘H:\javascript-demo’,
exports: {},
filename: ‘H:\javascript-demo\index.js’,
loaded: false,
children: [],
paths: [ ‘H:\javascript-demo\node_modules’, ‘H:\node_modules’ ]
}
其中的 exports 表示模块暴露的内容,当其他 node.js 文件引入该模块时,加载的就是 exports 指向的对象
【例】自定义一个 user 模块,然后在另一个 js 文件里引入它并执行
user.js
module.exports={
name: 'user.js',
user: {
name: 'uni',
age: 22
},
getUser(){
return JSON.stringify(this.user)
}
}
index.js
const user = require('./user')
console.log(user.getUser())
运行结果
{“name”:“uni”,“age”:22}
4. npm 包
Node.js 中的第三方模块又叫做包。
全球最大的包共享平台 https://www.npmjs.com/,这上面有上百万的开源包可以使用。
Node.js 使用的包管理工具为 Node Package Manager,在安装 node.js 后,系统变量会设置好支持 npm 命令的环境,之后就可以在终端使用 npm 命令
【例】通过 npm 安装 moment 时间处理的包,输出格式化的时间
npm install moment
如果是在一个文件夹里运行这个命令,那么就会产生以下这三个文件
- node_modules ,存放所有已安装到项目中的包,require() 导入第三方包时就是从这个目录中查找并加载包
- package-lock.json,记录 node_modules 目录下每一个包的下载信息,例如包的名字、版本号和下载地址等
- package.json,记录与项目有关的配置信息
const moment = require('moment')
const dt = moment().format('YYYY-MM-DD HH:mm:ss')
console.log(dt) // 2022-08-17 14:54:29
在使用 npm install 命令时候,在包名添加@版本号 可安装指定的版本,例如:
npm install moment@2.22.2
在安装后 package.json 里的内容为:
{
"dependencies": {
"moment": "^2.22.2"
}
}
版本号规范
Node 包的版本号是以点分隔的,共有三个数字,比如:1.1.10
分别表示:
- 第1位数字,大版本号
- 第2位数字,功能版本
- 第3位数字,Bug修复版本
版本号升级的规则:只要前面的版本号升级,那么后面的版本号都归零
注:nodule_module 比较占空间,而在共享项目时不用附带,因为只要有 package.json 配置文件,一执行 npm install 命令就会下载文件里指定的所有依赖。
npm 提供了快捷命令 npm init -y 初始化,-y表示直接同意命令中的提示,这个命令有个问题,就是不支持中文的路径,所以node项目最好不要包含中文名路径
4.1 切换 npm 镜像
npm 默认下载地址为国外的:https://registry.npmjs.org/,下载速度没有国内的镜像站快
// 查看当前的下包镜像源
npm config get registry
// 将下包的镜像切换为淘宝镜像源
npm config set registry=https://registry.npm.taobao.org/
// 检查镜像源是否下载成功
npm config get registry
除了上述这种手动替换 npm 镜像的方式以外,可以安装一个 nrm 小工具来实现镜像的切换
# 将 nrm 安装为全局可用的工具
npm i nrm -g
# 查看所有可用的镜像源
nrm ls
# 将下载包的镜像源切换为 taobao 镜像
nrm use taobao
4.2 包的分类
npm 中的包主要有项目包 和 全局包这两种,被安装到项目的 node_modules 目录中的包都是项目包。
4.2.1 项目包
项目包分为两大类,分别是:
- 开发依赖包( package.json 中 devDependencies 节点记录的包)
- 核心依赖包( package.json 中 dependencies 节点记录的包)
npm i 包名 -D // 开发依赖包, 会被记录到 devDependencies
npm i 包名 // 核心依赖包, 会被记录到 dependencies
4.2.2 全局包
在执行 npm install 命令时,若添加 -g 参数,那么安装的包则可以在全局使用
安装包的目录在:
C:\Users\用户目录\AppData\Roaming\npm\node_modules
注:只有工具性质的包,才有全局安装的必要性
4.3 包的规范
包一般符合以下三点规范:
- 包必须以单独的目录存在
- 包的顶级目录下必须包含 package.json 这个包管理配置文件
- package.jon 必须包含 name、version 和 main 这三个属性,分别代表包的名字、版本号和包的入口
4.4 案例-开发自定义的包并发布
4.4.1 开发包
自定义一个包,实现时间处理以及 HTML代码解码和编码的功能
项目结构
|- uni-tools
|- src
|- dateFormat.js 时间处理脚本
|- htmlEscape.js HTML内容特殊字符处理脚本
|- package.json 包管理配置文件
|- index.js 包的入口文件
|- README.md 包的说明文档
|- demo.js 该脚本用于测试 uni-tools 的功能, 不属于包的一部分
- 配置包的信息,package.json
{
"name" : "unirithe-demo",
"version" : "1.0.0",
"main" : "index.js",
"description" : "提供了格式化时间, HTMLEscape的功能",
"keywords" : ["uni", "dateFormat", "escape"],
"license" : "ISC"
}
- 分别开发时间处理和 HTML 内容解析模块
dateFormat.js
// 定义格式化时间的函数
function dateFormat(dateStr){
const dt = new Date(dateStr)
const y = padZero(dt.getFullYear())
const m = padZero(dt.getMonth() + 1)
const d = padZero(dt.getDay() )
const hh = padZero(dt.getHours())
const mm =