node.js

简介

node.js是一个跨平台javascript运行环境,开发者可以搭建服务器端的javascript应用程序;node.js还可以进行前端工程化,对前端代码进行压缩、转译和整合,提高前端开发和运行效率。

所谓的前端工程化是指开发项目到上线,整个过程中集成的所有工具和技术,比如格式化工具、压缩工具、转换工具以及后续框架中用到的脚手架工具等。而node.js是前端工程化的基础(因为node.js可以主动读取前端代码内容)

浏览器之所以能够执行js代码,依靠的是内核中的V8引擎,而node.js是基于Chrome V8引擎进行封装的。但是注意node.js环境中没有DOMBOM等对象

安装

直接从官网中选择需要的版本进行下载,下载本地之后按照正常软件安装步骤进行安装即可,最后记得添加环境变量,具体的安装教程可参考csdn或其他博客。

最后在cmd中执行node -v可以验证是否成功安装

image-20250319221027028

快速体验

node环境下执行js代码,通过node xxx.js即可

编写简易js代码,在node环境下执行

1
2
3
for (let i = 1; i <= 10; i++) {
console.log(i)
}

image-20250319221734689

nodejs常用模块

fs模块

fs模块用于读写文件,封装了与本机文件系统进行交互的方法和属性

语法

  1. 加载fs模块

    1
    const fs = require("fs") //fs是模块标识符(模块的名字)
  2. 写入文件内容

    1
    2
    3
    4
    fs.writeFile("文件路径","写入的内容",err=>{
    //写入后的回调函数
    //如果写入过程中出现了错误,err参数会有具体的值
    })
  3. 读取文件内容

    1
    2
    3
    4
    fs.readFile("文件路径",(err,data)=>{
    //读取后的回调函数
    //data是文件内容的Buffer数据流,err是异常信息
    })

实例

1
2
3
4
5
6
7
8
9
10
11
12
const fs = require("fs")
fs.writeFile("./fn_write.txt", "nodejs fs模块写入文件", err => {
console.log("内容已将全部写入文件!!!")
})

fs.readFile("./fn_write.txt", (err, data) => {
if (err) {
console.log("读取失败")
} else {
console.log(data.toString())
}
})

image-20250319225536809

Path模块

node.js中的Path模块主要用于路径处理

比如在node.js代码中,相对路径是根据终端所在路径去查找的,可能无法找到你想要的文件,而在代码中编写的相对路径通常是依据当前js文件所在的路径去查找的,所以在编写时尽量实用绝对路径,可以通过__dirname这个内置变量,获取当前js文件所在目录的绝对路径。

path.join()会使用特定于平台的分隔符作为定界符,将所有给定的路径片段连接在一起

1
2
3
4
5
6
const path = require("path")

//获取当前文件的绝对路径
let filePath = path.join(__dirname, "demo01.js")

console.log(filePath)

http模块

nodejshttp模块可以用于创建web服务,并响应内容给浏览器

http模块创建web服务的步骤:

  1. 加载http模块,创建web服务对象
  2. 监听request请求事件,设置响应头和响应体
  3. 配置端口号,启动服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//引入http模块
const http = require("http")
//创建web服务对象
const server = http.createServer()
//监听request事件
server.on("request", (req, res) => {
//设置响应头
res.setHeader("Content-Type", "text/plain;charset=utf-8")
//设置响应体
res.end("欢迎访问由nodejs创建的web服务")
})

//配置端口号,启动服务
server.listen("8000", () => {
console.log("web服务启动...")
})

image-20250325145500987

案例—基于web服务,开发提供网页资源功能

浏览器请求资源网页,后端响应指定网页内容,包括html标签、css样式和js等字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//引入模块
const http = require("http")
const fs = require("fs")
const path = require("path")
//创建web服务对象
const server = http.createServer()
//监听request事件
server.on(`request`, (req, res) => {
if (req.url == "/random.html") {
//请求对应的页面
fs.readFile(path.join(__dirname, "dst/random.html"), (err, data) => {
res.setHeader("Content-Type", "text/html;charset=utf-8")
res.end(data.toString())
})
} else {
res.setHeader("Content-Type", "text/plain;charset=utf-8")
res.end("访问的资源不存在")
}
})

server.listen("8000", () => {
console.log("web服务启动...")
})

dst/random.html的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.container {
margin: 10px auto;
width: 300px;
height: 300px;
/* background-color: antiquewhite; */
text-align: center;
}

.num {
width: 200px;
height: 200px;
margin: 10px 30px;
text-align: center;
font-size: 50px;
font-weight: 700;
line-height: 200px;
background-color: aquamarine;
}

.div_button {
margin: 10px auto;
display: flex;
justify-content: space-between;
}

button {
width: 50px;
height: 30px;
background-color: bisque;
}
</style>
</head>

<body>
<div class="container">
<div class="num">0</div>
<div class="div_button">
<button class="start">开始</button>
<button class="end">结束</button>
</div>
</div>

<script>
let numTag = document.querySelector(".num")
let startButton = document.querySelector(".start")
let endButton = document.querySelector(".end")
let intervalId;
startButton.addEventListener(`click`, function () {
let val = Number(numTag.innerText);
intervalId = setInterval(() => {
val += 1
numTag.innerText = val
}, 50)
})

endButton.addEventListener(`click`, function () {
if (intervalId) {
clearInterval(intervalId)
}
})
</script>
</body>

</html>

访问http://localhost:8000/random.html即可看到如下内容

image-20250325152705997

nodejs模块化

node.js中,每个文件都被视为一个单独的模块,一个项目是由多个模块文件组成的

模块化的好处:提高代码的复用性、按需加载、独立作用域

commonJS标准—导入和导出

如何自定义模块供其他模块使用:

  • 需要按照标准语法(CommonJS标准)导出导入进行使用

  • 导出语法

    1
    2
    3
    4
    5
    module.exports={
    对外属性名1:xxx,
    对外属性名2:xxx,
    ......
    }
  • 倒入语法

    1
    2
    3
    require("模块名或者路径")
    //如果是nodejs内置模块,直接写名字,比如fs、path、http等
    //如果是自定义模块,则写模块文件路径

示例

dst目录下创建一个utils.js文件

1
2
3
4
5
6
7
8
9
10
const url = "https://www.today.com"

const add = (num1, num2) => {
return num1 + num2
}

module.exports = {
"url": url,
"add": add
}

在另一个文件里去导入utils.js模块

1
2
3
4
5
const utils = require("./dst/utils.js")

console.log(utils.url)
const res = utils.add(10, 20)
console.log(res)

ECMAScript标准—默认导出和导入

该标准的默认语法:

  • 导出语法

    1
    2
    3
    4
    5
    export default{
    对外属性名1:xxx,
    对外属性名2:xxx,
    ......
    }
  • 导入语法

    1
    import 变量名 from "模块名或者路径"

注意:

nodejs默认支持commonjs语法,如果需要使用ECMAScript标准语法,则需要在运行模块所在文件夹新建package.json文件,并设置{"type":"module"}

示例:

utils.js文件

1
2
3
4
5
6
7
8
9
10
const url = "https://www.today.com"

const add = (num1, num2) => {
return num1 + num2
}

export default {
"baseurl": url,
"add": add
}

demo01.js文件

1
2
3
4
5
6
import utils from "./dst/utils.js"


console.log(utils.baseurl)

console.log(utils.add(20, 40))

package.json文件

1
2
3
{
"type": "module"
}

ECMAScript标准—命名导出和导入

命名标准使用:

  • 导出:export修饰定义语句
  • 导入:import {同名变量} from 模块名或路径

如何选择默认导入和导出以及命名导入和导出?

  • 按需加载,使用命名导入和导出
  • 全部加载,使用默认导入和导出

示例:

utils.js文件

1
2
3
4
5
export const url = "https://www.today.com"

export const add = (num1, num2) => {
return num1 + num2
}

demo01.js文件

1
2
3
4
import { url, add } from "./dst/utils.js"

console.log(url)
console.log(add(20, 40))

总结

  • CommonJS标准:一般应用在Node.js项目环境中
  • ECMAScript标准:一般应用在前端工程化项目中

包的概念

包:将模块、代码以及其他资料聚合成一个文件夹

包的分类:

  • 项目包:主要用于编写项目及其业务逻辑
  • 软件包:封装工具和方法进行使用

包的要求:在根目录下,必须有package.json文件(包的说明清单文件)

package.json常见的内容:

1
2
3
4
5
6
7
8
{
"name":软件包的名称,
"version":软件包当前的版本,
"description":软件包的简短描述,
"main":软件包的入口点,
"author":软件包的作者,
"license":软件包的许可证(商用后可以用作者名字宣传)
}

注意:导入软件包时,引入的默认时index.js模块文件/main属性指定的模块文件,该文件是包的唯一出口;该文件的作用是将所有其他模块的方法集中起来,统一向外暴露

示例

项目目录如下:

image-20250326005627881

./lib/arr.js文件

1
2
3
4
5
6
7
8
9
const add = function (arr) {
return arr.reduce((sum, val) => {
return sum + val;
}, 0)
}

module.exports = {
"add": add
}

./lib/str.js文件

1
2
3
4
5
6
7
8
9
10
11
12
const len = (str) => {
return str.length
}

const upp = (str) => {
return str.toUpperCase()
}

module.exports = {
"len": len,
"upp": upp
}

index.js文件

1
2
3
4
5
6
7
8
const { add } = require("./lib/arr.js")
const { len, upp } = require("./lib/str.js")

module.exports = {
add,
len,
upp
}

test.js文件

1
2
3
4
5
const utils = require("./utils")

console.log(utils.add([2, 5, 7, 9]))
console.log(utils.len("hjj"))
console.log(utils.upp("klkljh"))

npm

npm — 软件包管理器

npmnode.js标准的软件包管理器,安装node.js只会,npm工具也会一同被安装,它能够下载和管理node.js包依赖

image-20250326010255247

如何使用npm来下载和管理包依赖:

  • 初始化清单文件

    1
    2
    3
    npm init -y
    //该命令会自动生成package.json文件,如果当前项目存在该文件,则略过此命令
    //package.json里面除了记录前面介绍的那些内容外,还会记录当前项目下载了哪些包
  • 下载软件包

    1
    npm i 软件包名称  #下载对应的软件包
  • 使用软件包

    • 在项目需要的地方导入和使用相关的软件包及其模块

示例:

新建文件夹npm_demo,在该文件夹下执行npm init -y,会生成package.json文件

1
2
3
4
5
6
7
8
9
10
11
12
{
"name": "npm_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

下载第三方依赖dayjs,执行npm i dayjs

package.json文件中会记录当前项目下载的依赖包的名称和版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "npm_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dayjs": "^1.11.13"
}
}

对应第三方包会下载在该项目下的node_modules文件夹下

image-20250326151732859

在当前项目中导入第三方包,使用相关工具模块

1
2
3
4
const dayjs = require("dayjs")

const date = dayjs().format("YYYY-MM-DD")
console.log(date)

npm—安装所有的依赖

场景:从第三方得到的项目文件,里面有package.json文件,但是没有存储第三方依赖包的node_modules文件夹(这是因为用npm下载依赖比用磁盘传递拷贝要快得多),为了能够让项目成功运行起来,需要安装项目涉及到的所有第三方依赖

此时需要执行npm i命令,其会下载package.json中记录的所有软件包

npm—全局软件包nodemon

  • 本地软件包:当前项目内使用,封装了一些属性和方法,存在于项目目录下的node_modules文件夹
  • 全局软件包:本机所有项目均可使用,封装了一些命令和工具,存在于系统设置的位置

nodemon的作用:替代node命令,检测代码更改,自动重启程序

nodemon的使用:

  • 安装:npm i nodemon -g-g代表安装到全局环境
  • 运行:nodemon xxx.js来执行目标js文件

其能感知代码文件变化,自动重启程序

image-20250326153842673

删除软件包

npm uni 软件包名称

执行该命令后,会从node_modules中删除对应包依赖,并且会从package.jsonpackage-lock.json这两个文件中删除相应的记录

image-20250326154811477