nodejs学习笔记01 JavaScript运行环境-基本使用-模块化-npm-简单使用

node学习笔记01

前置知识

为什么JavaScript可以在浏览器中被执行?

浏览器中有JavaScript解析引擎,可以将待执行的JS代码解析执行。
不同的浏览器使用不同的JavaScript解析引擎: Chrome浏览器 => V8解析引擎
在这里插入图片描述

为什么JavaScript可以操作DOM和BOM

JS通过调用浏览器提供的内置Web API来操作DOM和BOM
在这里插入图片描述

浏览器中的JavaScript运行环境

运行环境:代码正常运行需要的环境

1.V8引擎负责解析和执行JavaScript代码
2.内置API是由运行环境提供的特殊接口,只能在所属的运行环境中被调用
在这里插入图片描述

Nodejs概述

Nodejs是基于Chrome V8 引擎的JavaScript运行环境

  • 浏览器是JavaScript的前端运行环境
  • Nodejs是JavaScript的后端运行环境,可以让JavaScript进行后端开发

Nodejs中的JavaScript运行环境

基于V8引擎,但是不是浏览器运行环境,所以Nodejs中无法调用DOM和BOM等浏览器内置API
在这里插入图片描述

基本命令

执行node: node js文件路径

fs文件系统模块

fs模块是Node.js内置的操作文件的模块。

模块使用步骤
1.引入模块
2.使用模块

const fs = require('fs') 

内置变量与方法

  • __dirname: 当前文件所处的目录
  • fs.readFile(): 读取指定文件中的内容
  • fs.writeFile(): 向指定的文件中写入内容

fs.readFile() 读取指定文件中的内容

语法: fs.readFile(path[,options],callback)

  • path:表示文件的路径
  • options:设置读取文件的编码格式,默认指定uft8
  • callback:文件读取完成后,通过回调函数拿到读取的结果
    • 参数1: 读取失败之后,用于接收失败的信息
    • 参数2: 读取成功之后,接收读取的数据
const fs = require('fs');
fs.readFile('./1.txt','utf8',function(err,dataStr){
	/*
	dataStr成功的结果,err失败的结果
	读取成功err用null
	*/
})

fs.writeFile() 向指定的文件中写入内容

语法: fs.writeFile(file,data[,options],callback)

  • file 文件的路径
  • data 写入的内容
  • options 指定写入文件内容的格式,默认值是utf8
  • callback 写入完成后的回调函数
    • 参数 写入失败之后,用于接收失败的信息
const fs = require('fs');
fs.readFile('./1.txt','abc',function(err){
//文件写入成功err是null
})

使用说明
1.fs.writeFile()方法只能用来创建文件,不能用来创建路径
2.重复调用fs.writeFile()写入同一个文件,新的内容会覆盖新的内容

练习-考试成绩整理

需求
在这里插入图片描述
思路1
1.使用fs.readFile读取成绩.txt文件
2.获取到内容之后,根据空格进行分割数组,循环替换
3.合并数组通过换行\r\n连接数组中的每个元素

const fs = require('fs')
fs.readFile('./files/成绩.txt', 'utf8', function(err, dataStr) {
  if (err) return console.log('读取文件失败!' + err.message)
  const arrOld = dataStr.split(' ')
  // 循环分割后的数组,对每一项数据,进行字符串的替换操作
  const arrNew = []
  arrOld.forEach(item => {
    arrNew.push(item.replace('=', ':'))
  })
  //把新数组中的每一项,进行合并,得到一个新的字符串
  const newStr = arrNew.join('\r\n')

  // 调用 fs.writeFile() 方法,把处理完毕的成绩,写入到新文件中
  fs.writeFile('./files/成绩-ok.txt', newStr, function(err) {
    if (err) {
      return console.log('写入文件失败!' + err.message)
    }
    console.log('成绩写入成功!')
  })
})

path路径模块

path模块是Node.js内置的处理路径的模块

  • path.join(): 将多个路径片段拼接成一个完整的路径字符串
  • path.basename(): 从路径字符串中,将文件名解析出来
const path = require('path');

path.join() 路径拼接

语法:path.join([…paths])
返回值:拼接好的路径字符串

路径中出现../ 在当前拼接好的路径上回退一层。

../ 表示上一层目录
./ 表示当前目录

const pathStr = path.join('/a','/b','../') // \a

path.basename() 获取路径中的文件名

作用:获取路径中的最后一部分,通常通过这个方法获取路径中的文件名
语法: path.basename(path[,ext])

  • path:表示一个路径的子字符串
  • ext: 表示文件扩展名
    • 没写会显示文件扩展名
    • 写了之后会省略文件扩展名
  • 返回值: 路径中的最后一部分
const path = require('path')
const fpath = '/a/b/c/index.html'

const fullName = path.basename(fpath)
console.log(fullName)//index.html

const nameWithoutExt = path.basename(fpath, '.html')
console.log(nameWithoutExt) //index

path.extname() 获取路径中的文件扩展名

语法: path.extname(path)

const fpath = '/a/b/c/index.html'

const fext = path.extname(fpath)
console.log(fext) //.html

http模块

http模块是Node内置创建Web服务器的模块,将普通的电脑变成Web服务器

const http = require('http')

IP地址是互联网上每台计算机的唯一地址
端口号:表示一台电脑中的每个Web服务,在实际应用中url中的80端口可以省略

创建最基本的web服务器

1.导入http模块
2.创建web服务器实例 server = http.createServer
3.为服务器实例server .on绑定request事件,监听客服端的请求,客户端请求服务器会触发request请求
4.启动服务器server.listen(端口号,回调函数)

const http = require('http')
const server = http.createServer()
server.on('request', (req, res) => { 
	//客户端请求服务器会触发request请求
})
server.listen(8080, () => {  
  //服务器启动成功的回调函数
})

只要服务器接收到了客户端的请求,就会触发request事件,调用request事件处理函数。
request事件处理函数的参数

  • 第一个参数req请求对象:存储客户端相关的数据或属性
    • req.url : 客户端请求的URL地址
    • req.method: 客户端请求的method类型
  • 第二个参数res响应对象:存储服务器相关的数据或属性
    • res.end(响应的内容):向客户端响应指定内容,并结束本次请求。

问题1:当res.end()发送中文内容时,会出现乱码
解决办法: 设置响应头 Content-Type的值为text\html;charset = uft-8

server.on('request', (req, res) => {
  const str = `您请求的 URL 地址是 ${req.url},请求的 method 类型为 ${req.method}`
  // 调用 res.setHeader() 方法,设置 Content-Type 响应头,解决中文乱码的问题
  res.setHeader('Content-Type', 'text/html; charset=utf-8')
  res.end(str)
})

根据不同的url响应不同的html内容

1.获取请求的url地址
2.设置默认的响应内容为404 Not found
3.不同url的处理
4.设置Content_Type 响应头,防止中文乱码
5.使用res,end()把内容响应给客户端

server.on('request', (req, res) => {
  const url = req.url
  // 设置默认的响应内容为 404 Not found
  let content = '<h1>404 Not found!</h1>'
  // 判断用户请求的是否为 / 或 /index.html 首页
  // 判断用户请求的是否为 /about.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')
  res.end(content)
})
向浏览器响应html、css、js资源文件

响应文件的流程 – 实际给客户端的还是字符串
在这里插入图片描述
请求index.html之后,发现html里面有依赖./index.css./index.js,会根据html所在的目录拼接文件名再去服务器请求资源

模块化

什么是模块化

模块:把一个大文件拆成独立并相互依赖的多个小模块
**模块作用域:**在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问\

模块化的好处

  1. 提高了代码的复用性
  2. 提高了代码的可维护性
  3. 可以实现按需加载

nodejs中模块的分类

  1. 内置模块,由Nodejs官方提供,如fs、path等
  2. 自定义模块,用户创建的每一个js文件都是自定义模块
  3. 第三方模块,由第三方开发出来的模块,使用前需要先下载

加载模块 require

使用require()方法加载其他模块时,会执行被加载模块中的代码

  • 内置模块 | 第三方模块 require('模块名')
  • 自定义模块 require(’请求路径‘) js后缀名可以省略,默认是以.js结尾,必须指定以./../开头的路径标识符
模块的加载机制

使用require()方法加载其他模块时,会执行被加载模块中的代码

  • 优先从缓存加载:模块在第一次加载后会被缓存,多次调用require()不会导致模块的代码被执行多次
  • 内置模块的加载优先级最高
  • require()加载自定义模块时,必须指定以./../开头的路径标识符
  • require()导入自定义模块,如果省略了文件的扩展名,Node会按顺序尝试加载 ①确切的文件名进行加载 ②补全.js扩展名进行加载 ③补全.json扩展名进行加载 ④ 补全.node扩展名进行加载 ⑤加载失败

当目录作为模块标识符,传递给require()进行加载时
1.先去目录下找package.json文件,并寻找main属性,属性值作为加载的入口
2.如果没有package.json文件或者main入口不存在或无法解析,尝试加载目录下的index.js
3.报错

向外暴露成员 module对象

在每个.js自定义模块中都有一个module对象,该对象存储了和当前模块有关的信息

Module {
  id: '.',
  path: '', //当前文件的存储目录
  exports: {}, //向外暴露成员
  filename: '', //当前文件的路径 目录+文件名
  //.....
}
module.exports 指向暴露的对象

在自定义模块中,module.exports对象,将模块内的成员暴露出去。

外界使用require()方法导入自定义模块时,得到的就是module.exports指向的对象

const age = 20

// 向 module.exports 对象上挂载 username 属性
module.exports.username = 'ranan'
// 向 module.exports 对象上挂载 sayHello 方法
module.exports.sayHello = function() {
  console.log('Hello!')
}
module.exports.age = age

// 让 module.exports 指向一个全新的对象 那么require引入是新对象
module.exports = {
  nickname: 'biubiu',
  sayHi() {
    console.log('Hi!')
  }
}
exports 指向暴露的对象

因为module.exports写起来复杂,所以提供另外一个对象exports对象
默认情况下,exports和module.exports指向同一个对象 exports==module.exports
如果人为修改了指向,最终会以module.exports为准。

CommonJs规范 总结

1.每个模块内部都有module对象,该对象代表当前模块
2.module变量的exports属性是对外的接口
3.require()方法加载是module.exports指向的对象

npm与包

Nodejs中第三方模块又叫做包,包基于内置模块封装出来的,提供了更高级、方便的API,极大的提高了开发效率。
npm是包管理工具。

初次装包完成后,在项目文件夹下增加了node_modules的文件夹和package-lock.json的配置文件

  • node_modules:存放所有已安装到项目的包,require()导入第三方包时,就是从这个目录中查找并加载包的
  • package-lock.json:记录node_modules目录下每一个包的名字、版本号、地址等下载信息

说明

  1. npm i xxx@版本号 @版本号可以省略,省略默认安装最新版本。
  2. 多次安装同一个包,后面的会覆盖前面的
  3. 包的版本号: 大版本: 功能版本: Bug修复版本 前面版本号增长了,后面的版本号就归零

包分类

  • 项目包:安装到项目node_modules目录中的包
    • 开发依赖包:devDependencies节点中的包, 只在开发阶段会用到,项目上线后不会使用
    • 核心依赖包:dependencies 开发和上线都使用,默认会下载到dependencies节点
  • 全局包:在执行npm install命令时,使用-g参数,会把包安装为全局包

项目包的安装与卸载

npm install #一次性安装dependencies下的所有包
npm install 包名 # 安装包到dependencies下
npm install 包名 --save-dev # 安装包到devDependencies下
npm install 包名 -D # 简写形式
npm uninstall 包名 # 会自动从package.json的dependencies中移除包信息

全局包的安装与卸载

npm i 包名 -g # 全局安装指定的包
npm uninstall 包名 -g # 卸载全局安装的包

包管理配置文件 package.json

npm规定,在项目根目录下,必须提供package.json的包管理配置文件,用于记录项目的配置信息如项目名称、版本号、使用的包等。

创建package.json的快捷命令: npm init -y

该快捷命令只能在英文的目录下成功运行,目录不能有空格

npm镜像服务器

在这里插入图片描述
切换npm的下包镜像源 - 解决下包速度慢的问题

# 查看当前的下包镜像源
npm config get registry
# 切换
npm config set registry=https://registry.npmmirror.com

npm的包结构规范

1.包必须以独立目录存在
2.包的顶级目录下必须包含package.json这个包管理配置文件
3.package.json中必须包含name包名、version包版本号、main包的入口这三个属性

自定义包

登录之后
进入到包的根目录,npm publish发布包
运行npm unpublish 包名 --force 从npm删除已发布的包
1.只能删除72小时以内发布的包。
2.使用命令删除的包,在24小时内不允许重复发布。

初始化包结构

1.新建my-tools文件夹,作为包的根目录
2.新建package.json包管理配置文件、index.js包的入口文件、README.md包说明文件

初始化package.json

{
  "name": "my-tools", //包名不能重复
  "version": "1.0.0",//包版本号
  "main": "index.js",//包入口
  "description": "提供了格式化时间、HTMLEscape相关的功能",//包的描述信息
  "keywords": [//搜索关键字
    "my",
    "dateFormat",
    "escape"
  ],
  "license": "ISC" //开源许可协议
}

main属性的作用
如果导入的是一个目录,会先搜索这个目录是否有package.json文件,如果有则看有没有main属性,默认会导入main属性值的文件

1.格式化日期

将传入的时间进行格式化
分别获取年月日时分秒,进行格式拼接,不足10的补0

// 定义格式化时间的函数
function dateFormat(dateStr) {
  const dt = new Date(dateStr)

  const y = dt.getFullYear()
  const m = padZero(dt.getMonth() + 1)
  const d = padZero(dt.getDate())

  const hh = padZero(dt.getHours())
  const mm = padZero(dt.getMinutes())
  const ss = padZero(dt.getSeconds())

  return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}

// 定义一个补零的函数
function padZero(n) {
  return n > 9 ? n : '0' + n
}

module.exports = {
  dateFormat
}
2.转义HTML中的特殊字符

< > " &HTML的特殊字符转义成实体字符,防止用户提交表单时填写HTML字符串

// 定义转义 HTML 字符的函数
function htmlEscape(htmlstr) {
  return htmlstr.replace(/<|>|"|&/g, match => {
    switch (match) {
      case '<':
        return '&lt;'
      case '>':
        return '&gt;'
      case '"':
        return '&quot;'
      case '&':
        return '&amp;'
    }
  })
}
3.还原HTML中的特殊字符

转义HTML中的特殊字符的逆操作

// 定义还原 HTML 字符串的函数
function htmlUnEscape(str) {
  return str.replace(/&lt;|&gt;|&quot;|&amp;/g, match => {
    switch (match) {
      case '&lt;':
        return '<'
      case '&gt;':
        return '>'
      case '&quot;':
        return '"'
      case '&amp;':
        return '&'
    }
  })
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值