node.js基础

node.js基础

🍓什么是node.js

  • 定义: node.js是一个基于Chrome V8 引擎的JavaScript运行环境(后端javaScript运行环境)
    浏览器属于JavaScript前端运行环境
  • node.js官网:https://nodejs.org/en

🍓node.js模块

  • 📌引入模块的方式

    js 复制代码
    //引入fs模块(内置模块和三方模块需要写上模块名)
    const fs = require('fs')
    
    //引入自定义模块(自定义模块需要写上js路径)
    const dataFormat = require('./dataFormat.js')
  • 📌模块分类

    • 🍁内置模块:
      fs、path、http
    • 🍁自定义模块:
      用户创建的每一个js文件,引用自定义模块,需要通过相对路径使用
    • 🍁第三方模块
  • 📌模块作用域
    在模块中定义的全局变量var,作用域只在模块自己内部,可以解决全局变量被污染的问题

  • 📌向外暴露模块作用域的成员:
    每一个.js自定义模块中都有一个module对象,module对象中的成员exports对象用来对外暴露模块作用域中的成员

🍒🍒 内置模块

🍅🍅🍅fs模块

引入fs内置模块

js 复制代码
const fs = require('fs')
  1. 📌fs模块用于操作文件

  2. 📌fs.readFile(path[, options], callback) 读取文件

    • 🍁path:必选参数,文件路径-字符串
    • 🍁options:可选参数,编码格式
    • 🍁callback:必选参数,文件读取成功的回调函数
      形参:
      • 🌷err:失败的结果
      • 🌷dataStr:成功的结果
    js 复制代码
    fs.readFile('C:\\Users\\Desktop\\abc.txt', 'utf8', (err, dataStr) => {
        if(!err) {
            console.log(dataStr);
        } else {
            console.error(err)
        }
    });
  3. 📌fs.writeFile(path, data[, options], callback) 写文件

    • 🍁path:必选参数,文件路径-字符串
    • 🍁data: 必选参数,写入内容
    • 🍁options:可选参数,编码格式
    • 🍁callback:必选参数,文件编写成功的回调函数
      形参:
      • 🌷err:失败的结果
    js 复制代码
    fs.writeFile('C:\\Users\\Desktop\\1.txt', "你好,nodejs", 'utf8', err => {
        if(err) {
            console.log(err)
        }
    })
  4. 📌fs.mkdir(path[, options], callback )创建目录

    • 🍁path:必选参数
    • 🍁options:可选参数(对象)
      • 🌷recursive
        true:递归创建
        false:不会递归创建
    • 🍁callback:必选参数,文件夹创建成功的回调函数
      形参:
      • 🌷err:失败的结果
      • 🌷path:文件夹路径,返回创建的第一层级的目录
  5. 📌fs.rmdir(path[, options], callback )删除目录

    • 🍁path:必选参数
    • 🍁options:可选参数(对象)
      • 🌷recursive
        true:递归删除
        false:不会递归删除
    • 🍁callback:必选参数,文件夹删除成功的回调函数
      形参:
      • 🌷err:失败的结果
      • 🌷path:文件夹路径,返回创建的第一层级的目录
  6. 📌fs.unlink(path, callback) 删除文件

    • 🍁path:必选参数
    • 🍁callback:必选参数,文件删除成功的回调函数
      形参:
      • 🌷err:失败的结果

🍅🍅🍅path模块

路径问题nodejs执行js时,js中的相对路径是参照node命令执行所在的目录,而不是参照js文件所在的目录

  1. 📌使用绝对路径(不推荐)
    缺点:
    移植性非常差,不利于维护
  2. 📌__dirname:代表当前文件所处的目录(不推荐)
    缺点:
    1. 🍁路径需要通过拼接的形式生成
    2. 🍁只能处理当前目录以下的文件,当前目录之前的文件无法处理
  3. 📌path模块(推荐)

引入path内置模块

js 复制代码
const path = require('path')

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

const fpath = '\a\b\v\index.html';
console.log(path.basename(fpath))   //index.html
console.log(path.basename(fpath, '.html')) //index
console.log(path.extname(fpath))    //.html
  • 🍁join(path0,path1,path2...,pathn):拼接多个路径,一个../消除一个前面的路径
  • 🍁basename(path[, ext]):获取文件名称
  • 🍁extname(path):获取文件的扩展名

🍅🍅🍅http模块

引入http模块

js 复制代码
const http = require('http')
  1. 📌http模块用于创建web服务

  2. 📌创建http服务

    1. 🍁引入http模块
    2. 🍁创建web服务器实例
    3. 🍁为服务器绑定request事件,监听客户端的请求
    4. 🍁启动服务器
    js 复制代码
    //1. 引入http模块
    const http = require('http')
    //2. 创建web服务器实例
    const server = http.createServer()
    //3. 为服务器绑定request事件,监听客户端的请求
    server.on('request', function(req, res){
        const url = req.url
        const method = req.method
        console.log(`Your request url is ${url}, and request method is ${method}`)
        res.setHeader('Content-Type', 'text/html;charset=utf-8')
        res.end('你好,nodejs')
    })
    //4. 启动服务器
    server.listen('8080', ()=>{
        console.log('server is runnging at http://127.0.0.1:8080')
    })
  3. 📌request事件回调函数

    • 🍁req:
      • 🌷req.url :获取请求路径
      • 🌷req.method :获取请求方式
    • 🍁res
      • 🌷res.end(str) :结束本次请求,并向客户端发送指定内容
      • 🌷res.setHeader(key, val) : 设置响应头

🍒🍒自定义模块

node.js中,自定义模块暴露成员通过挂载在module.exports对象上,其中exports对象默认也是内存地址指向module.exports,只要在挂载的时候没有更改module.exports对象的地址或者更改exports对象的地址就不会有问题。

js 复制代码
//挂载属性
module.exports.name = '张三'

//挂载方法
module.exports.sayHello = () => {
    console.log('Hello world!')
}

//挂载属性
exports.age = 23

//注意:该方式修改了module.exports对象内存地址的指向,导致module.exports和exports指向的不是同一个地址,则exports挂载属性不会生效。
module.exports = {
	code:'0000',
	message:'成功!'
}

//注意:该方式修改了exports对象内存地址的指向,导致module.exports和exports指向的不是同一个地址,则exports挂载属性不会生效。
exports = {
	title:'爱好',
	content:'足球'
}

🍒🍒第三方模块

🍅🍅🍅npm

  • npm用于下载发布管理三方包,我们可以通过npm命令去下载安装一些三方包供我们项目使用
    查询包:https://www.npmjs.com/
    下载包:https://registry.npmjs.org/
  • node_modules是用于存放三方依赖的文件夹
  • package.json用于记录项目中使用的包,通过执行命令npm i来初始化项目,安装三方包

🍅🍅🍅包的分类

  • 📌项目包
    • 🍁定义:那些被安装到项目的node_modules目录中的包,被称为项目包
    • 🍁开发依赖包
      npm i {packageName} -D
      被记录到package.json文件中节点devDependencies下面的包被称为开发依赖包,只在开发期间会使用到
    • 🍁核心依赖包
      npm i {packageName}
      被记录到package.json文件中节点dependencies下面的包被称为核心依赖包,开发期间和项目上线后都会使用到
  • 📌全局包
    • 🍁安装全局包:npm i {packageName} -g
    • 🍁卸载全局包:npm uninstall {packageName} -g
    • 🍁全局依赖包会下载到C:\Users\用户目录\AppData\Roaming\npm\node_modules
    • 🍁注意:
      只有工具性质的包,才有全局安装的必要性,因为它们提供了好用的终端命令(一般官方文档里面会告诉你)

🍅🍅🍅规范包的组成结构

  • 包必须以单独的目录而存在
  • 包的顶级目录下必须包含package.json文件
  • package.json必须包含name、version、main这三个属性,分别代表包名、包版本、包的入口

🍅🍅🍅发布自己的包

  1. 📌在package.json中编写自己的包信息

    json 复制代码
    {
        "name":"{packageName}",  //必须与当前npm仓库中的包名不重名
        "version":"1.0.0",       //版本号
        "main":"index.js",       //包程序入口
        "description":"包的描述信息",
        "keywords":["","",""...] //检索包的关键字信息
        "license":"ISC"          //开源许可协议
    }
  2. 📌编写README.MD文档,写明使用此包的方式

  3. 📌注册npm账号
    https://www.npmjs.com/

  4. 📌在终端输入以下命令,登录npm账号(在此之前,一定要先把下包的镜像地址切换到npm官方服务器)
    npm login

  5. 📌在包的根目录下输入以下命令,即可发布包
    npm publish

🍅🍅🍅express

express是基于内置模块http的基础上封装的一套可以方便、快速的创建Web网站服务器或API接口服务器
安装
npm i express

🍓🍅🍅🍅express创建web服务器的步骤
  1. 📌引入express模块

  2. 📌创建web服务器

  3. 📌启动web服务,监听端口

    js 复制代码
    const express = require('express')
    
    //创建web服务器
    const app = express()
    
    //启动web服务,监听端口
    app.listen('80', ()=>{
        console.log('express server running at http://127.0.0.1')
    })
🍓🍅🍅🍅挂载路由

app.get(url, function)
app.post(url, function)

🍓🍅🍅🍅req获取请求参数
  • 📌获取url地址传参:(形如:http://127.0.0.1/user?name=张三&age=23
    req.query.{key}

  • 📌获取动态地址传参:(形如:http://127.0.0.1/query/1234
    req.params.{key}

  • 📌获取请求体数据
    req.body(需要配置解析请求体数据的中间件)

    js 复制代码
    app.get('/user', function(req, res) {
        console.log('进入GET /user')
        //req.query 获取url地址传参(http://127.0.0.1/user?name=张三&age=23)
        const name = req.query.name
        const age = req.query.age
        //向客户端响应内容
        res.send({name, age})
    })
    
    app.get('/query/:id/:name',(req, res) => {
        //req.params 获取url地址的动态参数(http://127.0.0.1/query/1234/张三)
        const id = req.params.id
        const name = req.params.name
        res.send({id, name})
    })
    
    //express.urlencoded({extended:false})
    //express.json()
    app.post('/add/user', express.json(), (req, res) => {
        console.log(req.body)
        res.send(req.body)
    })
🍓🍅🍅🍅app.use()函数
  • 📌挂载静态资源:
    app.use(express.static({static_path}))
    app.use('{地址前缀}', express.static({static_path}))
  • 📌路由模块化:
    app.use(模块路由)
    app.use({地址前缀}, 模块路由)
  • 📌注册中间件
    app.use({中间件名称})
🍓🍅🍅🍅路由模块化:

问题: 通过app去挂载路由,会导致js文件臃肿,难以维护,路由模块化可以解决这个问题

  1. 📌引入express模块

  2. 📌创建路由对象

  3. 📌挂载路由

  4. 📌暴露路由对象

  5. 📌app.use()注册路由对象

    js 复制代码
    //引入express模块
    const express = require('express')
    
    //创建路由对象
    const router = express.Router()
    
    router.get('/user/list', (req, res) => {
        res.send([{name:'张三',age:23},{name:'李四', age:24}])
    })
    
    //暴露路由(注意:这里不能使用exports = router)
    module.exports = router
    
    //注册路由
    const xxx = require('./xxx.js')
    app.use(xxx)
🍓🍅🍅🍅中间件
🍒🍒🍅🍅🍅定义中间件
js 复制代码
//普通中间件
const mw = function(req, res, next){
	//放行
    next()
}

//错误中间件
const mw = function(err, req, res, next){
	//放行
    next()
}
🍒🍒🍅🍅🍅注册中间件
  • 📌全局中间件注册:app.use(mw)

  • 📌单个局部中间件注册:app.get(url, 中间件, 函数)

  • 📌多个局部中间件注册:app.get(url, [中间件1, 中间件2, ..., 中间件n], 函数)

    js 复制代码
    //定义全局中间件
    const mw = function(req, res, next){
        console.log('最简单的中间件函数')
        //流转给后面的路由
        next()
    }
    //注册全局中间件
    app.use(mw)
    
    //定义中间件
    const mv2 = function(req, res, next){
        console.log('最简单的中间件函数2')
        next()
    }
    
    //挂载路由,监听客户端post请求,请求地址是/user
    //将中间件mv2注册为局部中间件
    app.post('/user', mv2, function(req, res){
        console.log('进入POST /user')
        throw new Error('服务器内部发生了错误!')
        res.send({code:'000000', msg:'请求失败!'})
    })
    
    //定义中间件
    const mv3 = function(req, res, next){
        console.log('最简单的中间件函数3')
        next()
    }
    
    //挂载路由,监听客户端动态地址传参
    //注册多个局部中间件
    app.get('/query/:id/:name', [mv2, mv3],(req, res) => {
        //req.params 获取url地址的动态参数(http://127.0.0.1/query/1234)
        const id = req.params.id
        const name = req.params.name
        res.send({id, name})
    })
  • 📌多个中间件之间,共享同一份reqres,我们可以在上游的中间件中为reqres挂载某些属性和方法为下游中间件使用
    调用顺序:(与中间件注册的顺序有关)
    客户端请求 => 中间件1 => 中间件2 => 中间件3 => ... => 中间件n => 响应客户端

🍒🍒🍅🍅🍅中间件的分类
  1. 📌应用级别的中间件
    通过app.use()、app.get()、app.post()绑定的

  2. 📌路由级别的中间件
    通过router.use()、router.get()、router.post()绑定的

  3. 📌错误级别的中间件(注意:错误的中间件一定要放在最后定义)
    app.use(function(err, req, res, next))

    js 复制代码
    //挂载路由,监听客户端post请求,请求地址是/user
    //将中间件mv2注册为局部中间件
    app.post('/user', mv2, function(req, res){
    console.log('进入POST /user')
    throw new Error('服务器内部发生了错误!')
    res.send({code:'000000', msg:'请求失败!'})
    })
    
    //定义全局错误中间件
    app.use(function(err, req, res, next){
    console.log('发生了错误:' + err.message)
    res.send(err.message)
    })
  4. 📌Express内置的中间件
    配置解析 application/json 格式请求体数据的内置中间件
    app.use(express.json())
    配置解析 application/x-www-form-urlencoded 格式请求体数据的内置中间件
    app.use(express.urlencoded({extended:false}))
    由于express解析请求体数据中间件在4.16.0之后才支持,在此版本之前使用body-parser中间件解析请求体

    • 🍁下载body-parser
      npm install body-parser
    • 🍁引入body-parser模块
    • 🍁调用app.use()注册中间件
      app.use(parser.json())
      app.use(parser.urlencoded({extended:false}))
🍒🍒🍅🍅🍅中间件解决跨域问题
  1. 📌安装cors中间件
    npm i cors
  2. 📌注册cors中间件为全局中间件
    app.use(cors())
  3. 📌cors相关的响应头
    • 🍁Access-Control-Allow-Origin:*|具体的http地址
      • 🌷*:允许任何请求访问
      • 🌷具体的http地址:如http://app.cn.nb:81,表示只允许这个ip开头的客户端可以访问
    • 🍁Access-Control-Allow-Headers
      • 🌷允许客户端发送的请求头
      • 🌷默认情况下,cors仅支持客户端发送如下的请求头:
        Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、Width、Content-Type(值仅限于text/plain、multipart/form-data、application/x-www-form-urlencoded
    • 🍁Access-Control-Allow-Methods
      默认情况下,cors仅支持客户端发起GET、PUT、HEAD请求

🍓node.js常用命令

shell 复制代码
# 1. node版本查看
node -v

# 2. 运行javaScript脚本
node xxx.js

# 3. npm版本查看
npm -v

# 4. 安装下载包(默认下载最新版本)
npm install {packageName}
npm i {packageName}

# 5. 安装下载包(指定下载版本)
npm install {packageName}@{version}
npm i {packageName}@{version}

# 6. 初始化项目,根据package.json安装三方包
npm install
npm i

# 7. 卸载包
npm uninstall {packageName}

# 8. 创建package.json
npm init -y

# 9. 安装下载开发环境的包
npm i {packageName} -D
npm i {packageName} --save-dev

# 10. 检查当前下包镜像源
npm config get registry

# 11. 切换下包镜像源
npm config set registry=https://registry.npm.taobao.org/

# 12. 使用nrm快速切换镜像源
## 12.1. 下载安装nrm,将nrm安装成全局可用的工具
npm i nrm -g
## 12.2. 查看所有可用的镜像源
nrm ls
## 12.3. 将下载的镜像源切换为taobao镜像
nrm use taobao

# 13. 安装全局包
npm i {packageName} -g

# 14. 卸载全局包
npm uninstall {packageName} -g

# 15. 登录npm账号
npm login

# 16. 发布包(包根目录下执行)
npm publish

# 17. md文件转html
## 17.1 下载安装i5ting_toc,将i5ting_toc安装成全局可用的工具
npm i i5ting_toc -g
## 17.2 md文件转html
i5ting_toc -f xxx.md -o
相关推荐
求知若饥2 小时前
NestJS 项目实战-权限管理系统开发(六)
后端·node.js·nestjs
理想不理想v15 小时前
webpack最基础的配置
前端·webpack·node.js
南城巷陌17 小时前
JWT认证机制在Node.js中的详细阐述
node.js·jwt认证机制·前端安全认证
理想不理想v19 小时前
node.js的简单示例
node.js
yrldjsbk19 小时前
使用Node.js搭配express框架快速构建后端业务接口模块Demo
node.js·express
维李设论19 小时前
Node.js的Web服务在Nacos中的实践
前端·spring cloud·微服务·eureka·nacos·node.js·express
CodeChampion21 小时前
60.基于SSM的个人网站的设计与实现(项目 + 论文)
java·vue.js·mysql·spring·elementui·node.js·mybatis
Domain-zhuo21 小时前
如何利用webpack来优化前端性能?
前端·webpack·前端框架·node.js·ecmascript
理想不理想v21 小时前
webpack如何自定义插件?示例
前端·webpack·node.js