node.js模块

在这里插入图片描述

前言

node中的三大模块:
    1)系统模块 核心模块 node中内置的模块
    2)第三方模块
    3)自定义模块
安装node:
傻瓜式安装 安装完node,自带node命令

测试node是否OK:
window + r 输入cmd node -v

运行node代码:
1)在vscode上安装一个插件 code runner
2)webstrom / idea 直接运行JS代码
2)通过node命令去运行 node server.js

1 什么是模块?

module就是模块的意思。
在node.js模块系统中,每个文件都被视为一个独立的模块。
node.js采用CommonJS规范实现了模块系统。
CommonJS规范规定了如何定义一个模块,如何暴露(导出)模块中的变量函数,以及如何使用定义好的模块。

    a)在CommonJS规范中一个文件就是一个模块。
    b)在CommonJS规范中每个文件中的变量函数都是私有的,对其他文件不可见的(都是隔离的)。
    c)在CommonJS规范中每个文件中的变量函数必须通过exports暴露(导出)之后其它文件才可以使用。
    d)在CommonJS规范中想要使用其它文件暴露的变量函数必须通过require()导入模块才可以使用。

2 Node模块导出和导入

2.1 Node模块导出数据几种方式:

  1. 通过exports.xxx = xxx导出
  2. 通过module.exports.xxx = xxx导出
  3. 通过global.xxx = xxx导出

注意点:
  无论通过哪种方式导出, 使用时都需要先导入(require)才能使用。
  通过global.xxx方式导出不符合CommonJS规范, 不推荐使用。

  module.exports = "字符串";//可以的。返回模块本身
  module.exports.msg = '字符串'//可以的
  exports.msg = '字符串'//可以的
  exports = '字符串'//不行的

导出和导入:

    方案一:
        导出:
            exports.xxx = xxx 或 module.exports.xxx = xxx 可以导出N个数据
        导入:
            let res = require("./a") res是一个对象,对象中包含了N个数据
            
    方案二: module.exports后面的导出会覆盖前面的导出(覆盖.xxx或之前的)
            module.exports = "hello" 导出hello;//只能导出一个数据的意思就是因为会覆盖
        导入:
            let res = require("./a") res就是一个hello、
        导出:
            module.exports = { name:"wc",age:100 } 导出一个对象
        导入:
            let res = require("./a") res就是一个对象

强调:

  1. 每个文件就是一个模块,在模块里面定义的变量、函数、类都是私有的。
  2. module 代表的当前模块 ,exports属性,代表向外提供接口(数据)。
  3. require加载模块,读取并执行一个js文件,然后返回该模块的exports对象
  4. 模块加载的顺序按照代码中出现的顺序
  5. 模块可以多次加载,第一次加载运行之后,会被缓存,第2次开始,就从缓存中取,就不会重新加载。

exports 和 module.exports的区别?

1)exports只能通过exports.xx = xx的形式,向外暴露数据。
2)module.exports 可以通过 module.exports.xx = xx的形式,向外暴露数据,也可以通过module.exports = xx的形式,向外暴露数据。

3 自定义模块

  自定义的模块,需要使用./../打头。
  导入模块时,后缀可以不写。

4 系统(核心)模块

  导入系统模块 导入系统模块时,不需要加./或者../
node内置了很多模块。

//require("http") 导入系统模块  导入系统模块时,不需要加./或者../
let http = require("http")
console.log(http); // 使用方式:http.xx ;本身是对象

let qs = require("querystring")
console.log(qs);

let fs = require("fs")
console.log(fs);  // fs.xx 

let url = require("url")
console.log(url);  // url.xx

 在node中,人家内置了非常多的模块,我们直接导入后,就可以使用。

核心模块之fs模块:
fs:filesystem 文件系统 操作文件或目录

url模块

将一个URL字符串转换成对象并返回。

语法:url.parse(urlStr, [parseQueryString], [slashesDenoteHost]);

接收参数:
    urlStr:               url字符串
    parseQueryString:     为true时将使用查询模块分析查询字符串,默认为false
    slashesDenoteHost:              
         默认为false,//foo/bar 形式的字符串将被解释成 { pathname: ‘//foo/bar' }
         如果设置成true,//foo/bar 形式的字符串将被解释成  { host: ‘foo', pathname: ‘/bar' }

例:url.parse(http://localhost:3000/phone/goods?name='wc'&age=100")
输出结果:

   Url {
            protocol: null, 协议
            slashes: null,
            auth: null,
            host: null, 主机(IP或域名) ***
            port: null, 端口
            hostname: null, 主机名 ***
            hash: null,
            search: '?name=%27wc%27&age=100%22', searchs查询字符串 ***
            query: 'name=%27wc%27&age=100%22', query查询字符串 ***
            pathname: '/phone/goods', pathname路径名 ***
            path: '/phone/goods?name=%27wc%27&age=100%22', path是路径 路径 = 路径名 + 查询字符串 ***
            href: '/phone/goods?name=%27wc%27&age=100%22'
        }
  1. url.parse(req.url)的使用:
    req.url是请求过来的路径。
    对象不能跟字符串类型的数据+拼接,否则对象会变成[object Object]从而无法使用。
    var str = JSON.stringify(obj); 可以将对象转化为字符
let urlObj = url.parse(req.url);//解析url
req.method = req.method.toLowerCase();//得到url中get或post方法
req.pathname = urlObj.pathname;//得到路径名
req.query = qs.parse(urlObj.query) //得到get请求下的url内的查询字符串
req.body = qs.parse(params) //得到post请求下的url内的查询字符串
 // req是请求对象,里面有method  url path  query
console.log(req.method);
console.log(req.pathname);
console.log(req.query);
console.log(req.body);//post方法中的请求体

一般需要调用url里面的pathnamequery请求参数。

const http = require("http");//载入模块
const url = require("url")
let server = http.createServer((req, res) => {
    // req 里面包含非常多的请求信息
    // http://localhost:3000/phone/goods?name='wc'&age=100"
    // 通过req.url得到的url没有协议,没有域名,没有端口
console.log(req.url); // 获取请求的url /phone/goods?name =% 27wc % 27 & age=100 % 22
    // urlObj 解析之后的url 解析之后变成对象了
    //好处: 变成对象就可以打点访问时面的属性了 对象.xx
let urlObj = url.parse(req.url)
 console.log(urlObj);//解析结果
 res.write("<h1>hello client~</h1>")
    res.end();
})
server.listen(3000, () => {
    console.log(`server is running on ${3000}`);
})

url.format(urlObject)的使用:

const http = require("http");//载入模块
const url = require("url")//载入模块
let server = http.createServer((req, res) => {
    var params = {
        protocol: 'https:',
        host: 'www.lagou.com',
        port: '8080',
        hostname: 'www.lagou.com',
        hash: '#position',
        search: '?name=zhangsan&age=20',
        pathname: '/a',
    } 
    // format 格式化 把一个对象格式化成一个串
    console.log(url.format(params)); // https://www.lagou.com/a?
    name = zhangsan & age=20#position
    res.write("<h1>hello client~</h1>")
    res.end();
})
server.listen(3000, () => {
    console.log(`server is running on ${3000}`);
})

querystring模块

查询字符串。
querystring:模块提供用于解析和格式化 URL 查询字符串的实用工具。 可以使用以下方式访问它: const qs = require("querystring");
qs.parse()将URL解析成对象的形式。
qs.stringify()将对象 序列化成URL的形式,以&进行拼接。

const http = require("http");//载入模块
const qs = require("querystring");//载入模块
const url = require("url")//载入模块
let server = http.createServer((req, res) => {
    // 请求地址
    let urlObj = url.parse(req.url)
    // 结果
    // Url {................
    //   }
    // console.log(urlObj);
    // console.log(urlObj.query);  // name=%27z3%27&age=100

    // qs 可以解析查询字符串  url.parse中第二个参数为true也可以解析查询字符串
    let qsObj = qs.parse(urlObj.query)
    console.log(qsObj); // { name: "'z3'", age: '100' }
    res.write("<h1>hello client~</h1>")
    res.end();
})

server.listen(3000, () => {
    console.log(`server is running on ${3000}`);
})
//qs.parse()将URL解析成对象的形式
//qs.stringify()将对象 序列化成URL的形式,以&进行拼接
var params = {
name: 'wangcai',
age: 20
} 
console.log(qs.stringify(params));//name=wangcai&age=20

fs模块

  File System文件系统

封装了文件或文件夹 相关的api
    得到文件与目录的信息:stat
    创建一个目录:mkdir
    创建文件并写入内容:writeFile,appendFile
    读取文件的内容:readFile
    列出目录的东西:readdir
    重命名目录或文件:rename
    删除目录与文件:rmdir,unlink

fs.writeFile();覆盖式,写文件写入内容,没有则先创建文件,在写入。
fs.unlink();删除文件
fs.rename();修改文件
fs.appendFileSync();追加式写入文件
…更详细的功能:传送门

const fs = require("fs")//引入模块
// fs提供的api,基本上都是两套,一套是同步的,一套是异步的
---------------------- 创建一个文件,写入内容,如果没有文件,会自动创建文件
// err 表示如果写入失败了,失败的原因都是err中
// ./ 表示生成在js文件同级
// 第一个参数文件名,第二个参数表示写入的内容  第三个参数是回调函数  回头再调
fs.writeFile("./nameceees.txt","hello fs",function(err){
    if(!err){
        console.log("写入成功~");
    }
});
---------------------- 删除文件
//err回调函数的第一个参数都是err 在node是叫错误优先
fs.unlink("./name.txt",function(err){
    if(!err) console.log("删除成功!");
})
---------------------- 修改文件
fs.rename("./name.txt","newName.txt",function(err){
    if(!err) console.log("修改成功!");
})
---------------------- 覆盖式写文件
fs.writeFile("./newName.txt","666",function(err){
    if(!err){
        console.log("写入成功~");
    }
});
---------------------- 追加式写文件
fs.appendFileSync("./newName.txt","888",function(err){
    if(!err){
        console.log("写入成功~");
    }
});

events模块

事件处理模块。

const EventEmitter = require("events");或者
const emitter = require("events");

emitter.on(name, f) 对事件name指定监听函数f
emitter.addListener(name, f) addListener是on方法的别名
emitter.once(name, f) 与on方法类似,但是监听函数f是一次性的,使用后自动移除
emitter.listeners(name) 返回一个数组,成员是事件name所有监听函数
emitter.removeListener(name, f) 移除事件name的监听函数f
emitter.removeAllListeners(name) 移除事件name的所有监听函数
emitter.emit()用来触发事件。它的第一个参数是事件名称,其余参数都会依次传入回调函数。

path模块

处理路由的  基本上,用Node写服务器,都会用到此模块。
let path = require("path"); // 导入path  系统模块  内置模块   处理路径 
// __dirname 获取当前文件所在的文件夹的绝对路径
let res = path.resolve(__dirname,"a.html") // resolve具备路径拼接的功能
console.log(res); // e:\代码\03-系统模块\a.html
=====================如果是/ 含义就不一样  如果遇到一个/ 表示回到根路径
let res = path.resolve(__dirname,"/a.html") // e:\a.html
console.log(res); // e:\a.html
// let res = path.resolve(__dirname,"/")   // e:\  根路径 
// console.log(res); // e:\  根路径 
=====================join纯粹是路径拼接;有没有/都一样
let res = path.join(__dirname,"abc")
console.log(res);  // e:\03-系统模块\abc

let res = path.join(__dirname,"/abc")
console.log(res);  //  e:\03-系统模块\abc
=====================extname获取后缀名
let res = path.extname("a.b.html")
console.log(res);  // .html

=====================relative用于将绝对路径转为相对路径
//path.relative(from, to)用于将绝对路径转为相对路径,返回从 from 到 to 的相对路径(基于当前工作目录)。
let res = path.relative("a","a/a.js")
console.log(res);  // a.js

path.resolve(__dirname,"a.html")
    resolve 在拼接时,如果遇到/ 表示根路径
    resolve有两个作用:
       1)路径拼接   path.resolve(__dirname,"a.html") 
       2)如果是/ 含义就不一样  如果遇到一个/ 表示回到根路径
       
path.join(__dirname,"abc")======= join纯粹是路径拼接;有没有/都一样
path.extname("a.b.html")======extname获取后缀名
path.relative("a","a/a.js")======relative用于将绝对路径转为相对路径
...

vm模块

const vm = require('vm');
let a = 1;
const log = `console.log(a)`;
// eval执行时会查找上下文,不干净的执行
eval(log);
// new Function 是可以产生一个执行环境 不依赖于外层作用域,必须包一层函数 模板引擎中会使用
newFunction
// 模板引擎用的是 new Function + with
let fn = new Function(log);
console.log(fn())
// 让字符串直接执行 并且在沙箱环境中,干净的环境
vm.runInThisContext(log);

http模块

利用http模块创建一台服务器:

    // 引入一个核心模块http
    let http = require("http");
    // 创建一台服务器
    let server = http.createServer();
    // 注册一个请求事件
    server.on("request",(req,res)=>{
        // 解决乱码 不需要记
        res.writeHead(200,{"content-type":"text/html; charset=utf-8"})
        // 给客户端响应数据
        res.write("<h1>hello 你好 客户端~</h1>")
        // 结束响应
        res.end();
    })
    // 监听一个商品,只要是一个服务,就要监听一个端口
    server.listen(3030,()=>{
        console.log("server is running on 3030~")
    })

5 第三方模块

5.1 下载安装第三方模块

npm  npm是一个下载器   当我们安装了node  自带了下载器
要下载第三方,默认是国外下载,配置让去国内下载,nrm

nrm可以换源:
    安装nrm  npm i nrm -g    只要-g,就可以使用nrm这个命令
    nrm use taobao  换成国内源  下载速度会快一点
    nrm ls  查看都有哪些源

  一个项目, 可能有N个第三方模块,我们就需要一个文件,来记录你项目中都使用了哪些第三方模块,在写项目时,先需要创建这样一个配置文件,它的主要作用就是记录,你的项目中都用到了哪些第三方模块/第三方依赖

npm init -y 初始化项目 生会一个配置文件,叫package.json文件。
此文件会对项目进行描述,主要的用来记录我们项目的依赖(使用了哪些第三方模块)。

生成的配置文件如下:

{
  "name": "nodeCode",  // 项目的名字
  "version": "1.0.0",  // 项目的版本
  "description": "",  // 项目的描述
  "main": "01-hello node.js",  // 项目的入口
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"  // 配置一些命令
  },
  "keywords": [], // 项目的关键字
  "author": "",  // 项目的作者
  "license": "ISC"  // 项目遵循的协议
   "dependencies": {/-------------------------项目依赖/
    "jquery": "^3.6.0",
    "react": "^17.0.2",
    "vue": "^2.6.14"
  },
  "devDependencies": {/-----------------------开发依赖/
    "less-loader": "^10.0.0",
    "webpack": "^5.40.0"
  }
}

  安装好的第三方模块会放在node_modules这个文件夹中的。
  同时生成package-lock.json用来锁死第三方模块的版本号。

  别人使用你的项目时,只要还有package.json文件就可以通过命令:npm i把所有第三方模块重新安装好。也就是配置项目所需的运行和开发环境。
模块:一个文件就是一个模块。
包:N个文件,放在一个文件夹中,就形成一个包,安装一jquery,最终就是一个包(依赖)
注意点:package.json文件中, 不能加入任何注释。

安装包:

    包(依赖)的类型:
        1) 开发依赖devDependencies(webpack)。
            在项目开发的过程中需要的依赖,但是项目上线时,不需要了,叫开发依赖。
            如:less 把less转成css的依赖 项目时,就不需要了。
            安装:npm install webpack -D -D表示安装的依赖是开发依赖。
        2) 项目依赖dependencies(vue) npm install vue -S 新版本可以省略。
            项目上线时,还需要的依赖,没有这个依赖,项目就运行不了,叫项目依赖。
            安装:npm install vue -S -S表示安装的是项目依赖。
            
        3) 同版本依赖peerDependencies。
        4) 捆绑依赖bundledDependencies npm pack打包时,可以把有些依赖打包进去。
        5) 可选依赖optionalDependencies。
    安装项目依赖:
        npm i xx -S 或 npm i xx --save
    安装开发依赖:
        npm i xx -D 或 npm i xx --save-dev
    注意点:
        1.将项目拷贝给其它人, 或者发布的时候, 我们不会将node_modules也给别人, 因为太大。
        2.因为有的包可能只在开发阶段需要, 但是在上线阶段不需要, 所以需要分开指定。
        
    npm i 所有的包都会被安装
    npm i --production 只会安装dependencies中的包
    npm i --development 只会安装devDependencies中的包

第三方模块express模块

  npm i express
使用:

    let express = require("express")
    let app = express();
    app.get("/",(req,res)=>{
        res.send("hello 客户端~")
    })
    app.listen(3333,()=>{
        console.log("server is running on 3333")
    })

以下所有模块以上方express代码为母板,不在重复写这些内容。

ejs模块

  npm i ejs
  ejs:一个模板引擎,默认情况下,你的模板中写的数据都是假数据,一般数据都是来自于数据库的。如果把数据库中的数据取出来,放到需要替换数据的地方,此时就是一个真数据,这个流程叫服务端渲染
使用:

var ejs = require("ejs");// 导入ejs模块
==================================路径写法一
app.use(express.static(path.join(__dirname,"public")))
// 1)告诉express,你的模板在什么地方
app.set("views",path.join(__dirname,"views"));//绝对路径的写法
==================================路径写法二
// 把./views目录设置为模板文件根,html文件模板放在view目录中
app.set("views", "./views");//告诉express,模板放在views下面
==============================================================================
// 设置模板引擎为ejs
// 2)告诉express,你使用的模板引擎是什么 ejs 除了ejs模板引擎之外,还有其它的模板引擎
app.set('view engine', 'ejs')
app.get("/xxx",(req,res)=>{
// res.send("hello express")
// 把数据渲染到模板中 通过res.render就可以渲染模板,同时就可以给模板上绑定数据
res.render('xxx',{msg:"dadaima"});
})

body-parser模块

  npm i body-parser
使用:

var bodyParser = require('body-parser')
// 配置bodyParser
app.use(bodyParser.urlencoded({ extended: false }))//告诉express解析表单数据
app.use(bodyParser.json())//解析json数据
//req.body就可以获取post请求的携带的数据

cookie-parser模块

  npm i cookie-parser
配置cookie
使用:

const cookieParser = require('cookie-parser')
app.use(cookieParser());//配置cookie

express-session模块

  npm i express-session
配置session
使用:

const session = require('express-session')
// 配置session
app.use(session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
    // session是基于cookie的
    cookie: { maxAge:60000*10 }
}))

cookie-session模块

  npm install cookie-session
配置cookie-session

var cookieSession=require('cookie-session');
app.use(cookieSession({
  name: 'lagou',
  secret:"lagouadmin",//秘钥
  maxAge:1000*60*60*24, // 能活一天
  cookie:{
    maxAge:1000*60*60*24,
  }
}))

bcrypt模块

  npm install bcrypt
对用户名进行加密

const bcrypt=require('bcrypt')//对密码进行加密处理
    // 比对密码是否正确
    _comparePwd(pwd, hash) {
        return bcrypt.compareSync(pwd, hash)
    }

    // 对密码进行加密  传进来password
    _createHashPwd(password) {//下划线开头 意味着在内部调 不会出去
        return bcrypt.hashSync(password, 10)//哈希值加密
    }
     // 密码入库之前,需要进行加密
        password = this._createHashPwd(password)

multer模块

  npm install multer
实现express中文件上传,一般写于中间件

// 之前普通的文本数据,通过body-parser就可以接收 (普通的表单数据)
let multer = require('multer')//上传文件需要这个模块
let path = require('path')

let uploadfile=(req,res,next)=>{
    console.log("文件上传");

    let fullpath = path.resolve(__dirname, "../public/upload");//指定下载到的路径

    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, fullpath)//指定下载到的路径
        },
        filename: function (req, file, cb) {
            let extname = path.extname(file.originalname);//文件后缀
            filename = file.fieldname + '-' + Date.now() + extname;//图片名字:
            // filename = file.fieldname + extname;//图片名字
            cb(null, filename)
        }
    })
    var upload = multer({ storage }).single('companyLogo');//companyLogo是文件的键名
    upload(req, res, function (err) {
        if(!req.file){// 如果上传文件不存在
            delete req.body['companyLogo'];//如果失败就删除它
            res.send("如果上传文件不存在,提示这个信息")
            next();//表示程序可以继续向下执行
            return;
        }
        if(err){// 如果出现错误,提示
            res.send({
                code:-1,
                message:"图片上传失败"
            })
        }else{
            req.body.companyLogo = filename;//这里只是放入body里它的这个文件名
            console.log("我就改个名字");
            next();//表示程序可以继续向下执行      
        }  
    })
    // next();
}
module.exports=uploadfile;

后续还会补充…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值