Node.js 是除了浏览器之外,可以运行 JavaScript 的 环境
Node.js 下运行 JavaScript
- 脚本模式
node path/filename.js (回车)
- 交互模式
使用 tab 键自动补全
探索 JavaScript 对象(例如:Math. 然后按两次 tab 键)
点命令(例如:输入 .help 然后回车)
node (回车) 进入交互模式
JS 代码 (回车) 运行代码
.exit或按两次 ctrl+c 退出交互模式
全局对象
Node.js 下的全局对象是 global
浏览器端的 JS 中,全局对象是 window
Node.js 下的全局对象是 global
- 在交互模式下,声明的变量和函数都属于 global
例如:var a = 1;global.a 可以访问到 - 在脚本模式下,声明的变量和函数都不属于 global
例如:var a = 1;global.a 访问不到
全局函数
Node.js 下的全局函数
- JavaScript 语言提供的全局函数,在 Node.js 下依然可用
parseInt/parseFloat/isNaN/isFinite/eval..
一次性定时器(setTimeout / clearTimeout)
周期性定时器(setInterval / clearInterval) - Node.js 环境也提供了一些全局函数
立即执行定时器(setImmediate / clearImmediate)
var num = 3.14
console.log(parseInt(num))
var timer = setTimeout(() => {
console.log(1)
}, 2000)
// 清除一次性定时任务
// clearTimeout(timer)
// 在事件队列开始之前,立即执行
setImmediate(() => {
console.log(2)
})
// 在主进程结束后立即执行
process.nextTick(() => {
console.log(7)
})
Node.js 模块
核心模块 - console
- 控制台中输出的内容,通过不同的颜色标识不同的变量类型
- 控制台中可以一次输出多个变量, 多个变量之间,用逗号分隔
- 官方文档:nodejs.cn/api/console…
console.log("1")
console.log(1)
var obj = {
name: 'Tom',
age: 18
}
console.log(obj)
console.table(obj)
// 计时函数
console.time('for') // 计时开始
for (let i = 0; i < 1000000; i++) {
}
console.timeEnd('for') // 计时结束
console.time('while')
var i = 0
while (i < 1000000) {
i++;
}
console.timeEnd('while')
核心模块 - process
- process 提供了有关当前 Node.js 进程的信息
- process 是全局变量,使用时无需 require 引入
- 官方文档:nodejs.cn/api/process…
// process 是全局变量,使用时,无需引入
// const process = require('process')
// console.log(process)
// 输出 node 版本
console.log(process.version)
// 输出操作系统架构
console.log(process.arch)
// 输出操作系统平台
console.log(process.platform)
// 输出当前工作目录 cwd = current working directory
console.log(process.cwd())
// 环境变量
console.log(process.env)
// 自定义环境变量
process.env.NODE_ENV = 'develop'
console.log(process.env)
// 获取进程的编号
console.log(process.pid)
// 杀死进程 process.kill(进程编号)
核心模块 - path
- path 模块提供了有关路径操作的函数
• 当前目录 ./
• 上一级目录 ../ - 使用之前,需要通过 require 引入
- 官方文档:nodejs.cn/api/path.ht…
// 引入 path 模块
const path = require('path')
// 获取当前文件所在的路径
console.log(process.cwd())
// dir = directory 目录
console.log(__dirname) // 获取当前文件所在的路径
// D:\cliu\Desktop\node\03.core_module\path.js
console.log(__filename) // 获取当前文件的完整路径
// 获取文件的扩展名 ext = extension
console.log(path.extname(__filename))
// 获取路径中的目录部分
console.log(path.dirname(__filename))
// 获取路径中的文件名
console.log(path.basename(__filename))
const t = path.join(__dirname, '..')
console.log(t)
// 将多个路径合并起来
const a = path.join('D:/', 'a', 'b', 'c.png')
console.log(a)
//D:\a\b\c.png
核心模块 - fs
- fs (file system) 提供了文件操作的 API
• 文件操作
• 目录操作 - 使用之前,需要通过 require 引入
- 官方文档:nodejs.cn/api/fs.html
文件写入操作
// 文件的写操作
const fs = require('fs')
// 清空写入
// fs.writeFile('文件路径', '写入内容', 回调函数)
fs.writeFile('./1.txt', '曾经有一首歌,她感动了我', (err) => {
if (err) throw err
console.log('写入成功')
})
文件读取操作
const fs = require('fs')
const path = require('path')
// 读文件
// 指定目标文件所在的路径
// var filename = __dirname + '/1.txt'
var filename = path.join(__dirname, '1.txt')
// 语法:fs.readFile('文件路径', 回调函数)
fs.readFile(filename, (err, data) => {
if (err) throw err
// data 是二进制数据,默认输出时,以十六进制的方式展示
console.log(data.toString())
})
文件删除操作
const fs = require('fs')
// 语法: fs.unlink('文件路径', 回调函数)
fs.unlink(__dirname+'/1.txt', (err) => {
if (err) throw err
console.log('删除成功')
})
文件追加写入操作
const fs = require('fs')
// 追加写入
// 语法: fs.appendWrite('文件路径','写入内容', 回调函数)
fs.appendFile(__dirname+'/2.txt', '曾经有一首歌,她是这样唱的\n', (err) => {
if (err) throw err
console.log('追加写入成功')
})
创建目录
const fs = require('fs')
// 创建目录
// 语法:fs.mkdir('目录路径', 回调函数)
fs.mkdir('./d1', (err) => {
if (err) throw err
console.log('创建成功')
})
删除目录
const fs = require('fs')
// 删除目录
// 语法: fs.rmdir('目录路径', 回调函数)
fs.rmdir('./d1', (err) => {
if (err) throw err
console.log('删除成功')
})
// 声明: rmdir 只能删除空目录
// 1. 先删除目录下的普通文件(清空目录)
// 2. 通过 rmdir 删除空目录
重命名目录
const fs = require('fs')
// 重命名目录
// 语法: fs.rename(旧名称, 新名称, 回调函数)
fs.rename(__dirname+'/d1', __dirname+'/d2', (err) => {
if (err) throw err
console.log('重命名成功')
})
读取目录
const fs = require('fs')
// 读目录
// 语法:fs.readdir('目录路径', 回调函数)
fs.readdir(__dirname, (err, data) => {
if (err) throw err
// console.log(data)
//遍历路径内容
data.map((d) => {
// console.log(d)
fs.stat(__dirname+"/"+d, (err, stat) => {
if (err) throw err
if (stat.isDirectory()) {
// 判断当前文件是否是目录
console.log('目录:', d)
} else if (stat.isFile()) {
// 判断当前文件是否是普通文件
console.log('文件:', d)
}
})
})
})
同步函数
const fs = require('fs')
// 先判断文件是否存在
// 然后,如果文件存在的化,再执行删除
if (fs.existsSync(__dirname+"/1.txt")) {
fs.unlinkSync(__dirname+"/1.txt")
} else {
console.log('文件不存在')
}
实现文件的复制和压缩
const fs = require('fs')
const path = require('path')
// 把 src/style.css 复制到 dist/ 目录下
const dist = path.join(__dirname, 'dist')
fs.readFile('./src/style.css', (err, data) => {
if (err) {
throw err
} else {
console.log(data.toString())
// 确保 dist 目录存在
if (!fs.existsSync(dist)) {
fs.mkdirSync(dist)
}
// 对文件进行压缩: 将无用的注释或空格去掉
// /* 注释的内容 */
var mydata = data.toString().replace(/\s+/g, '').replace(/\/\*{1,2}[\s\S]*\*\//g, '')
// 将读到的内容,写入目标文件
fs.writeFile(dist+'/style.min.css', mydata, (err) => {
if (err) throw err
console.log('成功')
})
}
})
文件流
const fs = require('fs')
// 1. 创建读取流
var readStream = fs.createReadStream('./file2.txt')
// 2. 创建写入流
var writeStream = fs.createWriteStream('./file_stream.txt')
// 3. 把读取流通过管道传给写入流
readStream.pipe(writeStream)
核心模块 - http
- http 模块可以发布 web 服务
- 使用之前,通过 require 引入
- 官方文档:nodejs.cn/api/http.ht…
const http = require('http')
// 1. 创建服务器
/**
* req = request 请求
* res = response 响应
*/
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('你好:Node.js')
})
// 2. 发布 web 服务
const port = 3000
const host = 'localhost'
// 在浏览器中访问 http://localhost:3000 然后能看到效果
server.listen(port, host, () => {
console.log(`服务器运行在 http://${host}:${port}`)
})
自定义模块
-
Node.js 中每个单独的 .js 文件,就是一个模块
-
每个模块中都有一个 module 变量,其代表当前模块
-
module 的 exports 属性是对外的接口
只有导出(module.exports)的属性或方法才能被外部调用 -
未导出的内容是模块私有,不能被外部访问 • 使用时,通过 require 引入
const PI = 3.14
//计算圆的周长
function perimeter(r) {
return 2 * PI * r
}
//计算圆的面积
function area(r) {
return PI * Math.pow(r, 2)
}
// 模块中的属性或方法,必须导出,然后才能被使用
module.exports = {
perimeter,
area
}
// 引入文件模块
const circle = require('./circle')
const r = 10
console.log('周长:', circle.perimeter(r))
console.log('面积:', circle.area(r))
模块的加载逻辑
文件模块
-
官方模块
require('path')
引入官方的核心模块 -
自定义模块
require('./circle')
引入自己定义的模块,后缀名.js可以省略
目录模块
-
以路径开头
require('./dir01')
找到指定路径下的dir01目录,然后引入入口文件 -
不以路径开头
require('dir02')
到当前目录下的node_modules目录中寻找dir02;如果找不到会到上一级目录寻找,直到顶层目录。找到目录模块dir02后,引入dir02中的入口文件。 -
确定入口文件
在目录中寻找package.json文件,入口文件通过其main属性指定,如果找不到,则默认引入index.js