Node.js 简介

运行环境

  • 浏览器是 Javascript 的前端运行环境
  • Node. js 的 Javascript 的后端运行环境
  • Node.js中无法调用 DOM 和 BOM 等浏览器内置的API

应用场景

fs 文件系统模块

读写文件

fs 模块是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求

tip 如果要使用 fs 模块需要先导入

const fs=require('fs')

读写文件方法

使用 fs.readFile()方法,可以读取指定文件中的内容

fs.readFile(path[,options],callback)
  • path 必选参数,字符串格式,表示文件路径
  • options 可选参数,表示指定编码格式来读取文件。
  • callback 必选参数,读取文件后的回调函数,函数形参 (err,dataStr)
    • err 读取失败的结果
    • dataStr 读取成功的文件内容

details 读取文件例子📄

const fs=require(fs)
fs.readFlie('./files/test.txt','ut8f',function(err,dataStr){
    // 失败的结果
    console.log(err)
    // 读取成功的文件内容
    console。log(dataStr)
})

使用 fs.writeFile() 方法,可以向指定的文件中写入内容

fs.writeFile(file,data[,options],callback)
  • file 必选参数,字符串格式,表示存放文件路径
  • data 必选参数,表示写入的内容
  • options 可选参数,表示指定编码格式来写入文件,默认 utf8 。
  • callback 必选参数,写入文件后的回调函数,函数形参 (err)
    • err 读取失败的结果

details 写入文件的例子📄

const fs=require('fs')
fs.writeFile('./files/test2.txt','Hello world!',function(err){
    // 可以通过判断 err 对象是否为null ,从而判断文件写入结果
    if(err){
         // 失败的结果
        return console.log('文件写入失败'+err.message)
    }
   console.log('写入成功')
    
})

路径动态拼接

warning 在使用 fs 模块操作文件时,如果提供的操作路径是以 ./ 或 …/ 开头的相对路径时,很容易出现路径动态拼接错误的问题

解决方案:采用 __dirname 拼接

// --dirname 表示当前文件夹所处路径
fs.writeFile(__dirname + './files/test2.txt','Hello world!',function(err){
    // 可以通过判断 err 对象是否为null ,从而判断文件写入结果
    if(err){
         // 失败的结果
        return console.log('文件写入失败'+err.message)
    }
   console.log('写入成功')
})

path 路径模块

path 模块是 Node.js 官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求

tip 如果要使用 path 模块需要先导入

const path=require('path')

path.join() 方法

作用:把多个路径片段拼接为完整的路径字符串

path.join([...paths])
  • ...paths <string> 路径片段的序列
  • 返回值:<string>

details 示例

const pathStr=path.join('/a','/b/c','../','./d','e')
// 输出 \a\b\d\e
console.log(pathStr)

const pathStr2=path.join(__dirname,'./files/1.txt')
// 输出 当前文件所处的文件目录\files\1.txt

warning 凡是涉及到路径拼接的操作,推荐使用 path.join() 方法进行处理。不要直接使用 + 进行字符串的拼接

path.basename() 方法

作用:可以获取路径中的最后一部分,经常通过这个方法获取路径中的文件名

path.basename(path[,ext])
  • path 必选参数,表示一个路径的字符串
  • ext <string> 可选参数,表示文件拓展名
  • 返回值:<string> 表示路径最后一部分

details 示例:获取路径中的文件名

const fpath='/a/b/c/index.html'
const fullName=path.basename(fpath)
// 返回值就是文件名 输出index.html
console.log(fullName)

const fullName2=path.basename(fpath,'.html')
// 返回值就是文件名去掉 .html 输出index
console.log(fullName1)

path.extname() 方法

作用:可以获取路径中的扩展名部分

path.extname(path)
  • path <string>必选参数,表示一个路径的字符串
  • 返回: <string> 返回得到的扩展名字符串

detaisl 示例:获取路径中的文件的扩展名

const fpath='/a/b/c/index.html
const fext =path.extname(fpath)
// 输出后缀名 .html
console.log(fext)

http 模块

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

tip 如果要使用 http 模块需要先导入

const http=require('http')

创建基本的服务器

// 导入http模块
const http=require('http')
//调用 http.createServer() 方法,创建一个 web 服务器实例
const server=http.creatServer()
// 用服务器实例的 .on 绑定为服务器 request 事件
// 即可监听客户端发送过来的网络请求
server.on('request',(req,res)=>{
    // 只要有客户端请求我们的服务器,就触发 requset 事件
    // 就会执行这个回调函数
    console.log('hello world')
    
    // req 是请求对象,包含客户端的数据和属性
    // 例如 req.url 是客户端的请求 url 地址
    // req.mothod 是客户端的请求类型
    
    // res 是响应对象 ,包含服务器的数据和属性
    // res.send() 给客户端发送指定内容 结束请求
    res.send('hello world') 
    // 给客户端发送 hello.. 并且结束请求
    
    //  res.end() 方法,向客户端发送中文时,
    // 会出现乱码问题,设置内容的编码格式
    // 设置响应头 Content——Type 的值为
    //  text/html; charset=utf-8
    res.setHeader('Content——Type','text/html; charset=utf-8')
})

// 调用服务器实例的 .listen(端口号,回调函数) 方法,启动当前的服务器实例
sever.listen(80,()=>{
    console.log('sever running at http://127.0.0.1:80')
})

tip 简陋路由功能的服务器

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

实现步骤

  1. 获取请求的 url 地址
  2. 设置默认的响应内容为 404 Not found
  3. 判断用户请求的是否为 / 或 /index.html 首页
  4. 判断用户请求的是否为 /about.html 关于页面
  5. 设置 Content-Type 响应头,防止中文乱码
  6. 使用 res.end() 把内容响应给客户端
// 导入http模块
const http=require('http')
//调用 http.createServer() 方法,创建一个 web 服务器实例
const server=http.creatServer()
// 用服务器实例的 .on 绑定为服务器 request 事件
// 即可监听客户端发送过来的网络请求
server.on('request',(req,res)=>{
    // 获取请求的 url 地址
 const url = req.url
    // 设置默认的响应内容为 404 Not found
    let content='404 not found!'
    // 判断
    if(url === '/' || url ==='/index.html'){
        // 用户请求是首页
        content = '首页'
    }else if(url === '/about.html'){
        // 用户请求是关于页
        content = '关于页面'
    }
    // 设置响应头防止中文乱码
    res.setHeader('Content——Type','text/html; charset=utf-8')
    // 发送内容给客户端
    res.send(content) 
})

// 调用服务器实例的 .listen(端口号,回调函数) 方法,启动当前的服务器实例
sever.listen(80,()=>{
    console.log('sever running at http://127.0.0.1:80')
})

模块化

概念

  • 模块化是指解决一个复杂问题时,自顶向下逐层把系统划分为若干模块的过程,模块是可组合、分解和更换的单元。
  • 模块化可提高代码的复用性和可维护性,实现按需加载。
  • 模块化规范是对代码进行模块化拆分和组合时需要遵守的规则,如使用何种语法格式引用模块和向外暴露成员。

分类

Node.js 中模块的分类

  • 内置模块
  • 自定义模块
  • 第三方模块

模块作用域

  • 和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域
  • 防止全局变量污染

模块作用域的成员

  • 自定义模块中都有一个 module 对象,存储了和当前模块有关的信息
  • 在自定义模块中,可以使用 module.exports 对象,将模块内的成员共享出去,供外界使用。导入自定义模块时,得到的就是 module.exports 指向的对象。
  • 默认情况下,exportsmodule.exports 指向同一个对象。最终共享的结果,以 module.exports 指向的对象为准

CommonJS 模块化规范

  • 每个模块内部,module 变量代表当前模块。
  • module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
  • 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。

模块加载机制

模块第一次加载后会被缓存,即多次调用 require() 不会导致模块的代码被执行多次,提高模块加载效率。

内置模块

加载优先级最高

自定义模块

加载自定义模块时,路径以 ./../ 开头,否则会作为内置模块或第三方模块加载。

导入自定义模块时,可以省略文件拓展名,Node.js 会按顺序加载文件

  1. 按确切的文件名加载
  2. 补全 .js 加载
  3. 补全 .json 加载
  4. 补全 .node 加载
  5. 报错

第三方模块

  • 若导入第三方模块, Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块。
  • 如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录

例如,假设在 C:\Users\fantasy\project\foo.js 文件里调用了 require('tools'),则 Node.js 会按以下顺序查找:

  • C:\Users\fantasy\project\node_modules\tools
  • C:\Users\fantasy\node_modules\tools
  • C:\Users\node_modules\tools
  • C:\node_modules\tools

目录作为模块加载

​ 当把目录作为模块标识符进行加载的时候,有三种加载方式:

  • 在被加载的目录下查找 package.json 的文件,并寻找 main 属性,作为 require() 加载的入口
  • 如果没有 package.json 文件,或者 main 入口不存在或无法解析,则 Node.js 将会试图加载目录下的 index.js 文件。
  • 若失败则报错