Skip to content

day01

目标**😗*

  1. nodejs:核心模块
  2. npm (包管理工具) + es6模块化
  3. yarn + webpack

Node.js是什么?

Node.js is an open-source, cross-platform JavaScript runtime environment.

  • 定义

    Node.js®是一个开源、跨平台的JavaScript运行时环境。

    ⇒ Node.js 是一个基于 Chrome V8 引擎JavaScript运行时环境

Untitled

Untitled

Untitled

  • Node.js 能做什么?
    1. 后端Web服务器开发/写接口
    2. 写爬虫
    3. 写应用程序
    4. 脚手架命令行工具

Node.js 发展历史

2008年 V8 引擎 随着 Chrome浏览器问世

Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型, 让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。

如果只有ECMAScript?

  1. 不能操作DOM, 不能监听click事件,不能发送ajax请求(浏览器提供的)
  2. 不能处理HTTP请求,不能操作文件

Node.js能干啥?

Node.js 作为一个 JavaScript 的运行环境,仅仅提供了基础的功能和 API。然而,基于 Node.js 提供的这些基础功能,很多强大 的工具和框架如雨后春笋,层出不穷,所以学会了 Node.js ,可以让前端程序员胜任更多的工作和岗位

  • 基于 Express/Koa 框架(http://www.expressjs.com.cn/),可以快速构建 Web 应用-->java
  • 基于 Electron 框架(https://electronjs.org/),可以构建跨平台的桌面应用-->安装,才可以使用的,开发一次,多平台运行
  • 基于 Crawler 框架(https://www.npmjs.com/package/crawler),可以快速开发爬虫应用->
  • 读写和操作数据库、创建实用的命令行工具辅助前端开发(后续框架中会一直使用的)
  • etc...

总之,Node.js 是大前端时代的“大宝剑”,有了 Node.js 这个超级 buff 的加持,前端程序员的行业竞争力会越来越强!

Node.js下载安装

Node官网 ⇒ 推荐 LTS (Long Term Support)

Node.js

01 首页

Untitled

02 下载

Untitled

安装

  • 安装就一直下一步就行了哈, 不要在中文文件夹目录下安装,默认选项不用修改,一直next
  1. 安装的过程全程下一步
    1. 不要改任何设置
  2. 注意!!!!!:
    1. 如非必要不要更改安装路径

查看是否安装好

windows ⇒ 按 win + R , 输入cmd ,打开终端 terminal 窗口, 执行下列命令

bash
node -v 
# 或者 
node --version
# 显示版本号,就说明安装好了

如果看不到:
关闭所有打开的终端,重新打开

常见的终端窗口

  • Windows
    • 自带 cmd (在文件夹路径位置,输入cmd,回车)
    • 自带 powershell (在文件夹路径位置,输入powershell ,回车)
    • 商店下载 Windows Terminal
    • 安装git之后,点 git bash here
jsx

如何使用Node.js 运行 Javascript 代码

新建一个文件 报错 touch “文件名”

Untitled

windows不支持touch命令

jsx
npm install touch-cli -g  全局安装后可以使用

方法一,终端里写代码 (了解)

cmd中输入node

Untitled

  1. 打开终端窗口:

  2. 输入node回车

  3. 输入语法正确的JS代码,比如:

    console.log('感觉自己萌萌哒!')
  4. 点击回车

  5. ctrl+c退出窗口

  6. 思考:

    1. 如果代码很复杂用这种方式你是否快乐?
jsx
console.log('wakaka')

// 退出
// 按住Ctrl + 按两次C

方法二,使用node执行js文件(掌握)

  1. 编写语法正确的.js文件
    1. 除了BomDom,基本都可以写
    2. console.log,setTimeout这些也提供了
    3. **注意!!!!:**是.js文件
  2. .js文件所在文件夹打开任意终端
    1. vscode 自带终端
    2. cmd
    3. power shell
    4. git bash
    5. ....
  3. 输入命令node xx.js
    1. xx.js是需要执行的文件名
    2. 中间有空格

补充:指定文件夹打开终端的方法:

  1. cmd:
    1. 文件夹路径处输入cmd,回车
  2. powershell
    1. 在文件夹路径处输入powershell,回车
  3. git bash
    1. 文件夹中直接鼠标右键git bash here即可
  4. vscode
    1. 在左侧资源管理中选中文件并右键
    2. 选择:在集成终端中打开
    3. **ctrl+`**可以快速切换终端的开关
    4. 注意:
      1. 初期不建议开多个

补充-终端使用技巧

  1. 方向键,可以切换历史命令
  2. tab可以自动补全
  3. cls或者clear可以清屏
  4. cd ../,cd 文件夹名... 路径切换
  5. ....

Q小结

刚才演示了如何使用Node.js:

  • 演示的两种方法中建议使用哪一种?
    1. node xxx.js
  • 电脑上有那么多的终端工具,建议用哪一种?
    1. 随便, 选一个自己喜欢的
    2. =⇒ mac 推荐 iterm2 =⇒ oh my zsh

global模块

类似于window对象,node中也有全局模块,在使用时不需要引入,直接使用

  1. 传送门:__dirname
  2. 传送门:__filename
  3. 传送门:console
  4. 传送门:setTimeout
jsx
/**
  * window 浏览器中的全局对象
  * global nodejs中的全局对象
  * 注意 : node里面使用 global里面的变量,不需要引入
  */
  
  //1. console.log()  打印

  //2. setTimeout 和setInterval ,延时器和定时器
  setTimeout(() => {
    console.log('123');
  }, 1000);

  // 模块作用域下的属性 
  //3. __dirname  当前文件夹的绝对路径
  //4. __filename 当前文件的完整路径, 包含当前文件
  //从当前所在磁盘盘符一直到当前文件夹的路径
   console.log(__dirname);
   console.log(__filename);

FS模块

fs模块是nodejs中最常用的一个模块,fs模块的方法非常多,今天咱们了解2个即可

文档地址:http://nodejs.cn/api/fs.html

注意:

  1. 除了global模块中的内容可以直接使用,其他模块都是需要加载的。
  2. fs模块不是全局的,不能直接使用。因此需要导入才能使用。
jsx
// 类似于浏览器中 script src="xx"
const fs = require("fs");

读取文件

首先是读取文件的方法

传送门:readFileSync

⇒ 中文

文件系统 | Node.js 中文文档 | Node.js 中文网

fs模块提供的读取文件的方法有很多种,咱们来学习这种同步的读取写法

⇒ 同步读取文件

写法1: 不考虑异常

jsx
// 写法1 不给编码格式 返回buffer对象
// const res = fs.readFileSync('./info/a.txt')
console.log('res:', res)
// 写法2 给编码格式
const res2 = fs.readFileSync('./info/a.txt', 'utf-8')
console.log('res2:', res2)

**写法2:**可以通过try-catch捕获

⇒ Buffer 缓冲对象

JavaScript 语言没有读取或操作二进制数据流的机制。 Buffer 类被引入作为 Node.js API 的一部分,使其可以在 TCP 流或文件系统操作等场景中处理二进制数据流。

https://www.runoob.com/nodejs/nodejs-buffer.html

jsx
1. Buffer对象是Nodejs用于处理二进制数据的。
2. 其实任意的数据在计算机底层都是二进制数据,因为计算机只认识二进制。
3. 所以读取任意的文件,返回的结果都是二进制数据,即Buffer对象
4. Buffer对象可以调用toString()方法转换成字符串。

Q:小结

  • readFileSync是哪个模块点出来的?
    1. fs
  • 不设置编码格式返回的是什么?
    1. 用进制的方式表示的Buffer数据

写文件

接下来咱们来学习如何写文件

传送门:writeFileSync

文件系统 | Node.js 中文文档 | Node.js 中文网

jsx
// 参数1 路径
// 参数2 内容
// 可以使用try-catch捕获异常
fs.writeFileSync('./info/a.txt','内容')

1. 基本使用
2. 文件不存在
3. 文件夹和文件均不存在

Q小结

刚才咱们演示了如何写文件:

  • writeFileSync是哪个模块点出来的?
    1. fs
  • 文件不存在是否会报错?
    1. 不会-->创建
  • 文件夹不存在是否会报错?
    1. 报错-->找不到

练习 - 成绩统计

结合刚刚学习的内容,咱们来完成一个成绩统计的案例

需求

  1. 读取成绩.txt中的成绩并进行累加
  2. 将累加的结果保存到,总成绩.txt
jsx
小明=98,小红=68,小黑=88,小绿=77,小王=59,小白=100

步骤:

  1. 读取数据
    1. fs.readFileSync
  2. 转换数据格式
    1. ,--->分隔 split--字符串-->数组
    2. =->split获取到数值
  3. 累加并保存
    1. 累加
    2. fs.writeFileSync
jsx
const fs = require('fs')
// 1. 读取数据
const scope = fs.readFileSync('./score/成绩.txt', 'utf-8')
// console.log('scope:', scope)

// 2.转换数据格式
// 根据,切换为 数组
const arr = scope.split(',')
// 基于数组 获取每一项中的数字
const numArr = arr.map(v => {
  // console.log(v.split('='))
  // 切割之后索引为1的值 str
  // +str-->数字
  return +v.split('=')[1]
})
// console.log('numArr:', numArr)

// 3.累加+保存
const total = numArr.reduce((pre, cur) => {
  return pre + cur
}, 0)
// console.log('total:', total)
// 不允许直接写入数字 转为 字符串
// 数字+''-->string
fs.writeFileSync('./score/总成绩.txt', total + '')

回顾

  1. Node.js
    1. JavaScript的运行时环境
    2. 它也可以解析js代码
  2. 如何用Node.js解析js
    1. node 文件名.js
  3. fs文件模块
    1. const fs = require('fs')
    2. 读取:fs.readFileSync
    3. 写入:fs.writeFileSync
    4. 成绩统计的案例
  4. reduce

路径动态拼接的问题

目前为止咱们终端所处路径和.js所在的路径相同,如果不相同呢?

⇒ 代码在运行的时候,会以执行node 命令时所处的目录(小黑窗),**动态拼接出(加上文件内部写的路径)**被操作文件的完整路径。

复现问题步骤:

  1. node切换到和.js不同级的目录

  2. 运用相对路径执行.js文件

    Untitled

  3. 测试基本逻辑js

  4. 测试上一节demo中的.js

  5. 测试使用绝对路径

路径动态拼接的问题

这一节咱们演示了路径动态拼接的问题:

  1. 执行node命令时,代码中的相对路径会和哪个路径动态拼接?
    1. 会和终端中的路径动态的拼接
    2. 不是和执行的js动态拼接
  2. 相对路径不靠谱,如何解决?
    1. 绝对路径

path模块

Node.js提供的处理路径的模块path,提供了很多处理路径的方法和属性,他也是一个内置模块

传送门:path模块

类似于FS模块,使用时需要先导入

jsx
const path = require('path')

方法很多,咱们了解其中的1个即可

  1. join

拼接-join

首先是join方法,他可以把多个路径片段拼接为完整的路径字符串,并且格式会和当前所在的操作系统一致

传送门

语法

  1. 基于文档确认语法

测试步骤

  1. 基于文档确认语法并进行测试
  2. 测试通过之后:
    1. 使用绝对路径读取文件

拼接-join方法

这一节咱们演示了如何通过join方法拼接路径:

  1. 利用join方法拼接路径和直接自己拼接的区别是?
    1. join更简单
    2. 根据具体的设备,生成不同的路径--->灵活
  2. 不同操作系统拼接出来的路径是否相同?
    1. \-/

http模块

今天的最后我们来学习http模块,并且结合他来开发一个静态资源服务器

为了更好的理解后续的代码,咱们来学习一些预备的知识

前置知识

当我们在浏览器中输入了www.baidu.com的时候,发生了什么?

  • ip地址 域名 端口三者之间的关系?
    • ip地址:
      • 任何一台设备(计算机, 手机, ...)想要接入到网络中(互联网,局域网),就会被分配一个唯一的ip地址
      • 通过这个ip地址就能找到这台设备
    • 域名:
      • 比如 www.jd.com 就是域名 ,方便记忆
      • 我们购买了服务器之后, 服务器会有一个IP地址, 我们可以通过域名解析让域名指向当前IP
      • 域名和ip地址绑定后,通过域名就可以找到对应的ip地址, 从而访问到该服务器
    • 端口:
      • 端口是计算机和外界通讯的虚拟通道
      • 一台计算机能运行很多程序, 一般一个程序会占用一个或者多个端口
      • http协议的默认端口是80
      • https协议的默认端口是443

Untitled

  1. 根据相关域名, 去查询dns服务器,得到对应的ip地址
  2. 根据IP地址, 找到对应的计算机
  3. 根据端口找到对应的服务器程序
  4. 根据url请求具体的信息
  5. 服务器根据上述信息发送请求
  6. 浏览器接收到了服务器的响应, 把结果响应出来

什么是http模块

http也是内置模块, Node.js 官方提供的、用来创建web 服务器的模块。

它提供了一系列的方法和属性,让开发者(咱们)可以用代码来创建服务器,接收请求及响应内容例如:

http.createServer() 方法,用来创建一个web 服务器,从而对外提供web 资源

如果要在 Node.js的代码中使用 http 模块,则需要先导入它

jsx
const http = require('http')

前置知识及http模块介绍

这一节咱们介绍了请求web服务器的基本流程,及Node自带的http模块:

  • url地址经由什么解析为ip地址?
    1. DNS解析服务器
  • http协议的默认端口是?
    1. 80

node提供了http模块可以让开发者创建web服务器

创建最基本的web服务器

接下来咱们基于官方的示例代码创建基本的web服务器

传送门:http模块

传送门:Node.js应用程序示例

步骤

  1. 导入 http 模块
  2. 创建 web 服务器实例
  3. 启动服务器
  4. 为服务器实例绑定request 事件,监听客户端的请求
jsx
// 1. 导入 http 模块 
const http = require('http');

// 2. 创建 web 服务器实例 
const server = http.createServer();

// 3. 启动服务器
server.listen(3000, () => {
    console.log(`server is running.... at 3000`);
});

// 4. 为服务器实例绑定 request 事件,监听客户端的请求 
// 当客户端发送请求到服务器的时候,会触发这个事件
server.on('request', () => {
    // 这里要处理客户端的请求
    console.log('hello yohuohuohuo');
});

端口号

计算机中的端口号

  1. 计算机和外部通讯的虚拟通道
  2. 范围是:0---65535
  3. 一个端口一次只能被一个服务占用:
    1. 比较靠前的端口很多已经被电脑默认的服务占用
    2. 一般给4位的没什么被占用
  4. 通过端口号来区分计算机提供的不同服务

Untitled

Q 小结

  • request事件什么时候触发?
    1. 有人访问服务器会触发
  • 一个端口一次可以被几个服务使用?
    1. 一个
  • 代码中的3000端口是否可以更换?
    1. 可以,有效即可

request对象和response对象

传送门:request

传送门:response

概念:

  1. 为了让开发者更好的接收请求的信息,及设置返回的内容
  2. request事件中提供了2个参数,分别是
    1. request
    2. response

request常见属性:

jsx
headers: 所有的请求头信息
method: 请求的方式(*)
url: 请求的地址(*)

response常见属性和方法

jsx
res.end(data); 结束请求,并且响应一段内容,相当于res.write(data) + res.end()
res.statusCode: 响应的的状态码 200 404 500
res.setHeader(name, value); 设置响应头信息, 比如content-type

测试:

  1. 输出request对象中的methodurl属性
  2. 通过statusCode属性设置不同的状态码
  3. 通过setHeader设置响应头
  4. 通过end设置不同的内容
  5. 注意:
    1. 代码更改之后需要ctrl+c关闭并重新运行
    2. favicon.ico的请求是浏览器自己发送的
    3. 返回的内容中如果有中文会乱码

解决中文乱码问题

当调用 res.end() 方法,向客户端发送中文内容的时候,会出现乱码问题,此时,需要手动设置内容的编码格式,下面给出一些content-type的设置方法

注意:

  • 部分内容可以省略content-type设置,浏览器可以自行推断
jsx
// 普通文本
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
// html
res.setHeader('Content-Type', 'text/html; charset=utf-8');
  • 如何理解requestresponse对象?
    1. request:
      1. 请求,http模块,客户端请求的信息 保存到了 request中方便调用
      2. url
      3. method
    2. response
      1. 响应,http模块为了让开发者,可以便捷的设置状态码,响应头,内容,提供了这么一个对象
      2. statusCode属性
      3. setHeader(key,value)
      4. response.setHeader('Content-Type', 'text/plain; charset=utf-8')
      5. end('内容')
  • 回调函数中requestresponse的名字是否可以修改?
    1. 可以--->形参

根据url响应不同的html内容

接下来咱们结合目前学习的知识来实现一个具体的效果

需求:

  1. url
    1. /或者/index.html--><h1>首页</h1>
    2. /about.html--><h1>about页面</h1>
    3. 其他----><h1>404 not found</h1>

练习-时钟案例

接下来结合目前所学的知识来完成一个demo

需求:

浏览器输入对应的url地址,读取并返回对应的文件

  1. /或者/index.html-->返回/clock/index.html
  2. /clock.css-->返回/clock/clock.css
  3. /clock.js-->返回/clock/clock.js
  4. 其他----><h1>404 not found</h1>

分析:

  1. 绝对路径读取文件需要导入?
    1. path.join()
    2. fs.readFileSync
  2. 返回读取的文件
    1. end方法响应内容
  3. 不需要设置utf-8的编码格式(读取文件不需要)
  4. 不需要设置content-type

实现静态WEB服务器

基于上一节的代码,调整为静态web服务器

  • 运行之后
  • 同一局域网中的用户输入
    • http://ip:端口/xxx.html
    • http://ip:端口/xxx.png
  • 即可访问服务器www目录中对应的文件

首先完成响应首页的逻辑

需求:

  1. 浏览器中输入/或者/index.html
  2. 读取并返回www目录中的index.html

分析:

  1. 准备工作:
    1. 创建www目录并整合上一节的时钟界面
  2. 绝对路径读取文件,需要导入哪些模块?
    1. fs
    2. path
  3. 返回读取的内容
    1. end方法响应内容
jsx
// 1. 导入 http 模块
const http = require('http')
const fs = require('fs')
const path = require('path')

// 2. 创建 web 服务器实例
const server = http.createServer()

// 3. 启动服务器
server.listen(8848, () => {
  console.log('my server start work')
})

// 4. 为服务器实例绑定 request 事件,监听客户端的请求
server.on('request', (request, response) => {
  // 判断地址 / 和 /index.html --->/index.html
  let url = request.url
  // 1./ /index.html 读取并返回 index.html
  if (url === '/' || url === '/index.html') {
    url = '/index.html'
  }
  // 读取并返回
  // 绝对路径 读取内容 响应给浏览器
  const fullPath = path.join(__dirname, './www', url)
  try {
    const res = fs.readFileSync(fullPath)
    response.end(res)
  } catch (error) {}
})

基于上一小节的逻辑,完成后续的代码

需求:

  1. 请求其他的资源,读取www目录中对应的文件并返回
  2. 读取失败响应404->not found

步骤:

  1. 生成读取的文件路径
    1. 基于url属性,生成绝对路径
  2. 返回读取的内容
    1. end方法

end~~~~~~~~~~~~


简介 | Electron

bash
npm install -g nodemon

nodemon [your node app]

node本地启动服务,同一个局域网下,要关闭电脑的防火墙才能访问。

自己手机开热点,ipconfig ; 关掉电脑防火墙; 可以访问

vite启动后提示"Network: use --host to expose",且无法通过网络IP访问服务_南桥几许的博客-CSDN博客_vite 局域网访问

jsx
const http = require('http');
const fs = require('fs')
const path = require('path')

const hostname = '127.0.0.1';
const port = 8888;
const server = http.createServer((req, res) => {

  const ip = req.socket.localAddress;
  console.log(ip)
});

// http://${hostname}:${port}/
server.listen(port, () => {
  console.log(`Server running at ${port}`);
});

server.on('request', (req, res) => {
  console.log(req.url)
  console.log(req.method)
  res.setHeader('Content-Type', 'text/html');
  const fullPath = path.join(__dirname, 'index.html')
  const fileHTML = fs.readFileSync(fullPath)
  res.end(fileHTML)
})

nodemon的安装

当我们修改了后台node服务器的代码之后,都需要重启node服务器。我们可以使用nodemon来自动重启服务

bash
# 全局安装nodemon
# npm 
npm install -g nodemon 
# or using yarn: 
yarn global add nodemon

Node.js-Web框架

  1. Express
  2. koa

Untitled

Mock数据

jsx
module.exports = [
    {
        "itemId": "597569", 
        "title": "老字号五谷芳乳鸽王(溪涌店)", 
        "imgUrl": "http://p1.meituan.net/w.h/deal/__9865128__6381104.jpg", 
        "score": "5.0", 
        "consumeNum": null, 
        "areaName": "", 
        "lowPrice": "79.0", 
        "saleNum": null, 
        "commentNum": 990, 
        "detailUrl": "", 
        "avgPrice": 80
    }, 
    {
        "itemId": "592274", 
        "title": "大渔铁板烧(福民店)", 
        "imgUrl": "http://p0.meituan.net/w.h/deal/__16971854__3919079.jpg", 
        "score": "4.8", 
        "consumeNum": null, 
        "areaName": "皇岗/水围", 
        "lowPrice": "175.8", 
        "saleNum": null, 
        "commentNum": 3523, 
        "detailUrl": "", 
        "avgPrice": 185
    }, 
    {
        "itemId": "1441497", 
        "title": "黄金海岸自助火锅(龙华店)", 
        "imgUrl": "http://p1.meituan.net/w.h/deal/b848f47a4623054c33c3d3aac5ebe3fb429108.jpg", 
        "score": "3.3", 
        "consumeNum": null, 
        "areaName": "龙华", 
        "lowPrice": "49.5", 
        "saleNum": null, 
        "commentNum": 1840, 
        "detailUrl": "", 
        "avgPrice": 39
    }, 
    {
        "itemId": "11000", 
        "title": "尊宝比萨(福强店)", 
        "imgUrl": "http://p0.meituan.net/w.h/mogu/3de8c301dc05d282670489ff477f34f0111729.jpg", 
        "score": "5.0", 
        "consumeNum": null, 
        "areaName": "皇岗/水围", 
        "lowPrice": "56.0", 
        "saleNum": null, 
        "commentNum": 4650, 
        "detailUrl": "", 
        "avgPrice": 45
    }
]