Node.js
(一)Node.js简介
1.1 概念
node.js是一个跨平台JavaScript运行环境,使开发者可以搭建服务器端的JavaScript应用程序
1.2 作用
使用node.js编写服务端程序
(1)编写数据接口,提供网页资源浏览功能等等
(2)前端工程化:为后续的vue和React等框架铺垫
前端工程化:开发项目直到上线,过程中所集成的所有工具和技术
1.3 执行js文件
Node.js能执行js文件,原因为:
(1)首先,浏览器能执行js代码,依靠的是内核中的V8引擎(c++程序);
(2)其次,node.js是基于chrome v8引擎进行封装!(node.js是运行环境)
(3)Node.js 环境中没有 BOM 和 DOM,但是也用 JS 语法。
1.4 Node.js 使用
(1)新建js文件,编写代码之后在node环境下运行;
(2)在vscode集成终端下,执行node xxx.js 回车即可执行
(二)模块
2.1 概念
模块:类似插件,里面封装了方法或属性。模块可以是 Node.js 内置的(如 fs、http 等),也可以是用户自定义的。
2.2 内置模块
2.2.1 fs模块-读写文件
fs模块:封装了与本机文件系统进行交互的,方法/属性。
(1)语法规则
- 加载fs模块对象
- 写入文件内容
- 读取文件内容
// 1.加载模块对象
const fs=requre('fs')
//2.写入文件内容
fs.writeFile('文件路径','写入内容',err=>{
// 写入后的回调函数
})
fs.readFile('文件路径',(err,data)=>{
// 3.读取后的回调函数
// data是文件内容的buffer数据流
})
(2)示例
test.js
const fs = require('fs')
fs.writeFile('./test/02demo.txt', '现在是测试阶段', (err) => {
if (err) {
console.log(err);
}
else {
console.log('写入成功');
}
})
fs.readFile('./test/02demo.txt', (err, data) => {
if (err)
console.log(err);
else {
console.log(data);//<Buffer e7 8e b0 e5 9c a8 e6 98 af e6 b5 8b e8 af 95 e9 98 b6 e6 ae b5>
// data是buffer 16 进制数据流对象
const str = data.toString()
console.log(str);//输出:现在是测试阶段
//读取成功
}
})
2.2.2 path模块-路径处理
path模块提供了一些实用工具函数,用于处理文件和目录的路径。
在跨平台开发中,不同操作系统(如 Windows 和 Unix/Linux)之间的路径格式有所不同(例如,Windows 使用反斜杠 \ 作为路径分隔符,而 Unix/Linux 使用正斜杠 /)。
path 模块提供了一系列用于处理路径的 API,包括但不限于:
路径的格式化:确保路径符合特定操作系统的要求,如将路径中的分隔符转换为当前操作系统支持的分隔符。
路径的拼接:将多个路径片段组合成一个完整的路径。
路径的解析:将路径字符串分解为目录名和文件名等组成部分。
路径的标准化:将路径中的多余或重复的分隔符去除,并将相对路径中的 … 和 . 转换成绝对路径的等效形式。
__dirname 在模块作用域内,是一个全局变量,它返回文件所在目录的绝对路径(作为字符串)
在node.js中,相对路径是根据终端所在路径来查找的,可能无法找到你想要的文件。故建议在node.js中使用绝对路径。
(1)语法规则
(1)加载path模块
const path = require('path');
(2)调用path模块方法
path 模块中常用的方法:
- **path.join([…paths])**将所有给定的 path 片段连接在一起,使用当前操作系统的分隔符作为定界符,然后规范化生成的路径。
- **path.dirname(path)**返回 path 的目录名,类似于 Unix/Linux 的 dirname 命令。
- **path.resolve([…paths])**将路径或路径片段的序列解析为绝对路径。给定的路径序列从右到左被处理,每个后续 path 被追加到前一个的 path 上,直到构造出绝对路径。
(2)示例
/**
* 目标:在node.js中 使用绝对路径
*/
const fs = require('fs')
//引入path对象
const path = require('path')
// 调用path.join方法配合_dirname
fs.readFile(path.join(__dirname, './test/02demo.txt'), (err, data) => {
if (err)
console.log(err);
else {
console.log(data);//<Buffer e7 8e b0 e5 9c a8 e6 98 af e6 b5 8b e8 af 95 e9 98 b6 e6 ae b5>
// data是buffer 16 进制数据流对象
const str = data.toString()
// 或者Buffer.from(data).toString('utf-8')
console.log(str);//现在是测试阶段
}
})
2.2.3 Http模块-创建web服务
前置知识:URL 是统一资源定位符,简称网址,用于访问网络上的资源.
Web服务程序:用于提供网上信息浏览功能
端口号的作用:标记服务器里对应的服务程序,值为(0-65535 之间的任意整数)
注意:http 协议,默认访问的是 80 端口.所有有些省略了。且0-1023 和一些特定的端口号被占用,我们自己编写服务程序请避开使用
(1)语法规则
(1)加载http模块,创建web服务对象;
(2)监听request请求事件,设置响应头和响应体;
(3)配置端口号并启动web服务;
(4)浏览器请求http://localhost:3000 测试
(2)示例
// 1.加载http模块,创建web服务对象
const http = require('http')
const server = http.createServer()
//2.监听request请求事件,设置响应头和响应体
server.on('request', (req, res) => {
// 设置响应头响应体
res.setHeader('Content-Type', 'text/plain;charset=utf-8')
res.end('您好,欢迎使用nodejs创建的web服务')
})
//3.配置端口号并启动web服务;
server.listen(3000, () => {
console.log('web 服务已启动');
})
// 4.测试:浏览器访问http://localhost:3000/
//控制台输出响应:您好,欢迎使用nodejs创建的web服务
2.3 自定义模块
首先需要了解两个概念:
CommonJS:CommonJS是一个规范,旨在统一JavaScript在服务器端环境中的模块化标准。它定义了模块的基本结构,包括如何导出(exports)和导入(require)模块。
ECMAScript模块:ECMAScript模块(ESM)提供了import和export语句,用于在模块之间导入和导出功能。
实现自定义模块,使用CommonJS或ECMAScript规范,其模块的导入和导出是不同的。
2.3.1 CommonJS标准
- 导出:module.exports{}
- 导入:require(‘模块名或路径’)
(1)语法
// 假设baseURL是一个字符串,getArrSum是一个函数
const baseURL = 'http://example.com';
function getArrSum(arr) {...}
导出语法:
module.exports = {
对外属性1: baseURL,
对外属性2: getArrSum
}
导入语法:require('模块名或路径')
使用:const obj=require('模块名或路径')
(2)示例
导出:
/**
* 目标:基于 CommonJS 标准语法,封装属性和方法并导出
*/
const baseURL = 'http://hmajax.itheima.net'
const getArraySum = arr => arr.reduce((sum, item) => sum += item, 0)
//导出模块对象
module.exports = {
url: baseURL,
arraySum: getArraySum
}
导入:
/**
* 目标:基于 CommonJS 标准语法,导入工具属性和方法使用
*/
// 导入
const obj = require('./test/04utils')
// 使用“
console.log(obj);
//{ url: 'http://hmajax.itheima.net', arraySum: [Function: getArraySum] }
console.log(obj.url);//http://hmajax.itheima.net
console.log(obj.arraySum([5, 1, 2, 4]))//12
2.3.2 ECMAScript标准
在Node.js中,默认情况下,.js 文件被视为遵循 CommonJS 模块规范。但是,从Node.js的某些版本(特别是从Node.js 12开始引入实验性支持,并在Node.js 14中进一步改进)开始,Node.js支持了ECMAScript模块(ESM)的原生实现。这意味着你可以在Node.js项目中使用ES模块(即使用import和export语句而不是require和module.exports)来组织你的代码。
(1)默认导出与导入
- 导出:export default
- 导入:import 变量名 from
导出:
// 导入导出语法
//导出语法
export default{
对外属性1: baseURL,
对外属性2: getArrSum
}
//导入
import 变量名 from '模块名或路径'
// 变量名的值接收的就是目标模块导出的对象
import obj from '模块名或路径'
//obj就等于export default导出的对象
导入
//导入:
/**
* 目标:基于 ECMAScript 标准语法,"默认"导入,工具属性和方法使用
*/
// 默认导入
import obj from './test/05utils.js'
console.log(obj);
console.log(obj.url);
console.log(obj.arraySum([10, 20, 30]))
// { url: 'http://hmajax.itheima.net', arraySum: [Function: getArraySum] }
//http://hmajax.itheima.net
//60
(2)命名导出与导入
- 导出:export 修饰 定义的语句
- 导入:iimport { 同名变量 } from ‘模块名或路径’
// 命名导出
export const baseURL = 'http://hmajax.itheima.net'
export const getArraySum = arr => arr.reduce((sum, item) => sum += item, 0)
// 导入:
import { baseURL, getArraySum } from "./test/06utils.js";
console.log(baseURL);
console.log(getArraySum([1, 2, 3, 4, 5]));
// http://hmajax.itheima.net
//15
(3)命名vs默认导出导入
- 按需加载,使用命名导出和导入:export 修饰变量,import{变量} from
- 全部加载:使用默认导出和导入:export default; import 变量名 from
(三)包
3.1 包的概念
- 包:将模块、代码、其他资料聚合成一个文件夹.
- 分类:
- 项目包:主要用于编写项目和业务逻辑
- 软件包:封装工具和方法进行使用
- 要求:
根目录中,必须要有package.json文件,(记录包的清单信息)
- 包的使用:
在导入软件包时,引入的默认是index.js模块文件或在上图package.json里面的main属性指定的模块文件。 - 示例:
封装数组求和函数的模块,封装判断用户名和密码长度函数的模块,形成一个软件包,并导入到 index.js 中使用查看效果.
arr.js和str.js封装了模块,然后将其统一导出到server.js文件,然后在 index.js中统一导入,进行代码编写
3.2 包管理器NPM
npm:是node.js标准的软件包管理器,用于下载和管理node.js中的软件包。
3.2.1 NPM使用
- 初始化清单文件:npm init -y(得到 package.json 文件,有则跳过此命令))
- 下载软件包:npm i 软件包名称
- 使用软件包
3.2.2 示例
使用 npm 下载 dayjs 软件包到本地项目文件夹中,引入到 index.js
中格式化日期打印,运行观察效果
/**
1.初始化文件npm init -y(得到 package.json 文件)
2.使用npm i dayjs下载好之后,会在package.json文件中出现 "dependencies": {
"dayjs": "^1.11.12"
}也会出现一个package-lock.json文件是为了固化下载的软件包的版本。
同时会新增文件夹node_modules,里面有文件夹dayjs,然后往下就是dayjs的实现逻辑
3.使用dayjs软件包,来格式化日期。(导入)
* 使用 npm 下载 dayjs 软件包到本地项目文件夹中
* 引入到 index.js 中格式化日期打印,运行观察效果
*
*/
const dayjs = require('dayjs')
const date = dayjs().format('YYYY-MM-DD')//modules
console.log(date);
3.2.3 npm安装所有依赖
Bg:我们拿到了一个别人编写的项目,但是没有 node_modules,项目不能运行?因为缺少了项目需要的依赖软件包,比如要使用 dayjs 和 lodash 但是你项目里没有这个对应的源码,项目会报错的
Q:为何没有给我 node_modules?
A:因为每个人在自己的本机使用 npm 下载,要比磁盘间传递要快(npm 有缓存在本机)
Q:如何得到需要的所有依赖软件包呢?
A:直接在项目目录下,运行终端命令:npm i 即可安装 package.json 里记录的所有包和对应版本到本项目中的 node_modules.
3.2.4 全局软件包 nodemon
- 软件包区别:
- 本地软件包:当前项目内使用,封装属性和方法,存在于node_modules.
- 全局软件包:本机所有项目使用,封装命令和工具,存在于系统设置的位置。
- nodemon作用:替代node命令,检测代码更改,自动重启程序
- 安装:npm i nodemon -g (-g 代表安装到全局环境中);运行:nodemon 待执行的目标 js 文件.
(四)Node.js 小结
1.模块化:每个文件都是一个模块,独立作用域,按需加载,使用特定的标准语法导出和导入使用。
- Commonjs标准:
导出:module.exports{};
导入:require('模块名/地址')
- Ecmascript标准:
默认导出:export default;导入:import from
自定义导出:export 修饰定义语句;导入:import{同名变量}from
2.包:把模块文件,代码文件,其他资料聚合成一个文件夹。
- 分类:
- 软件包:封装工具和方法,一般使用 npm 管理
- 本地软件包:作用在当前的项目,封装属性/方法。供项目调用编写业务需求。
- 全局软件包:作用在所有项目,封装命令/工具,支撑项目运行。
- 项目包:编写项目需求和业务逻辑的文件夹
- 软件包:封装工具和方法,一般使用 npm 管理
3.node.js常用命令:
- 执行js文件 node xxx.js
- 初始化package.json: npm init -y
- 下载本地软件包:npm i 软件包
- 下载全局软件包 npm i 软件包 -g
- 删除软件包:npm uni 软件包