模块化的使用和认识express

模块查找原则

模块分为:核心模块、第三方模块和自定义模块

核心模块查找原则:到node安装目录中去查找

自定义模块查找原则:首先查看文件名称是否包含路径符号,如果包含路径符号,按照自定义模块查找。自定义的模块查找原则是:以当前位置为基准,查找文件,找到则引用,找不到则报错。如果不包含路径符号,则先按照核心模块查找,找到则引用;如果找不到再按照第三方模块查找,找到则引用;如果也找不到,则报错。

第三方模块查找原则:

​ 1.在执行的js文件的同级目录查找node_moblue文件夹,

2.在node_moblue中查找和模块同名的目录,

​ 3.进入这个文件夹中,查找package.json文件,在package.json文件中查找main属性,则引用main中的属性值指向的文件

​ 如果和模块同名的目录

​ 没有package.json文件

    如果没有main属性

​ main属性指向的文件不存在

​ 会在模块同名的目录中,查找index文件,即index.js/index.json/index.node文件 默认引入该文件

​ 4.如果在js执行的同级目录没有node_module目录,那么返回当前目录的上一级目录查找,如果找到则引用;如果也没有,继续向上查找,如果到达当前盘符依然没有找到,那么就报错

模块设置导出项

module是什么?

答:在node每个模块中,都有一个对象叫modlue,这个对象表示当前模块的本身

为什么需要导出项?

答:在node中每个模块有自己独立的作用域,当前模块的数据外界是无法使用的

怎么实现的导出项?

在moblue这个对象中有一个属性叫exports,在外部的模块访问当前模块时,不能访问当前模块的数据,但是可以访问当前模块对象中exports的属性。根据exprots的这种属性,可以将导出项添加到exports身上

为什么需要模块化?

模块化的目的在于,让项目的结构更加清晰,后期便于维护

设置单个变量的导出项

module.exports.age = 22;  

设置函数的导出项

module.exports = function (req,res) {
    
    console.log(req.url)
    console.log(req.method)
    
    res.send('响应完成'); 
}

设置对象的导出项

module.exports = {
    name: '随便',
    age: 200,
    sex: 'm'
};

module.exports 和exports

关系(原理):exporst = module.exporst = {};

特点:通过给对象拓展属性的方式,使用哪个都行

注意:

1.模块最终会暴露 module.exports 指向的对象,如果进行了对象提供,就不会暴露exporst指向的数据

2.推荐使用module.exports属性来设置导出项

//b.js设置两个导出项

module.exports = { //新的对象 地址
    name: '大春哥',
    age: 19,
    sex: '男'
}


exports = { //新的对象 地址
    name: '刘鹏飞',
    age: 16,
    sex: '女'
}

在app.js中获取模块

//app.js获取b的导出项

const b = require('./b');

console.log(b);

/**

{ 
    name: '大春哥',
    age: 19,
    sex: '男'
}

*/

//为什么打印是module.exports的导出项而不是exprots的导出项呢

初始化指向

初始状态的指向.png

赋值的指向

赋值新的对象的比较.png

hackerNews2.2模块化实现

模块化示例图

hackerNews的模块化.png

app.js(服务器)的代码简化

//http 
const http = require('http');

//引入路由
const routing = require('./routing');

//创建服务器
const server = http.createServer();

//服务器绑定事件
server.on('request',(req,res)=>{
  //使用路由
  routing(req,res);

});

//服务器监听端口
server.listen(9998,()=>{
  console.log('http://localhost:9998 服务器已启动')
})

router.js(路由)的简化

作用:路由模块,处理app.js的所有请求和响应,将任务分发给depart.js模块

//路由模块,处理app.js的所有请求和响应,将任务分发给depart.js模块

// 引入handler.js模块
const depart = require('./depart');

//导出项
module.exports = function (req,res) {

  if(req.url.startsWith('/index')||req.url=='/'){ // 响应主页 index页面
    depart.showIndex(req,res);

  }else if(req.url.startsWith('/details')){ //响应详情页的请求
    depart.showDetails(req,res);
    
  }else if(req.url.startsWith('/submit')){ //响应提交页的请求
    depart.showSubmit(req,res);
   
  }else if(req.url.startsWith('/assets')){ //响应其他的请求
    depart.showStaic(req,res);

  }else if(req.url.startsWith('/add') && req.method=="GET"){  //get 添加请求
    depart.addGet(req,res);
    
  }else if(req.url.startsWith('/add') && req.method=="POST"){ //post添加请求
    depart.addPost(req,res);
    
  }else{
    depart.notFind(req,res);
    
  }
  
}

handler.js(处理器)的简化

作用:处理路由模块分发的任务

//处理路由模块分发的任务

//引入 fs path art-template mime url querystring
const fs = require('fs');
const path = require('path');
const template = require('art-template');
const mime = require('mime');
const url = require('url');
const querystring = require('querystring');

//导出项
module.exports = {

  //处理获取主页的属性
  showIndex(req, res) {
    readData(data => {
      //将json字符串的数据转为对象
      console.log(data)
      //按照id排序
      data.list.sort((a, b) => b.id - a.id)
      //将模板和数据绑定
      let str = template(path.join(__dirname, 'views', 'index.html'), data);
      res.end(str);
    });
  },
   //处理获取详情页的属性
  showDetails(req, res) {
    //获取传来的id
    let id = url.parse(req.url, true).query.id;
    //调用读取文件函数
    readData(data => {
      //查找符合id的元素
      data = data.list.find(v => v.id == id);

      //将数据绑定到模板中
      let str = template(path.join(__dirname, 'views', 'details.html'), data);
      //将数据结构返回给浏览器渲染
      res.end(str);
    });

  },
    //处理获取提交页的属性
  showSubmit(req, res) {
    fs.readFile(path.join(__dirname,'views','submit.html'),(err,data)=>{
      if(err){
        return console.log('读取提交页出错啦',err)
      }
      res.end(data);
    });
  },
    //处理获取静态页面的属性
  showStaic(req, res) {
    fs.readFile(path.join(__dirname, req.url), (err, data) => {
      if (err) {
        return console.log('读取其他文件出错', err)
      }
      res.setHeader('content-type', mime.getType(req.url));
      res.end(data);
    });
  },
   //处理get添加元素的属性
  addGet(req, res) {
    //使用url模块的方法,将数据取出
    let info = url.parse(req.url,true).query;
    readData(data=>{
      //给info添加id
      info.id = data.list[data.list.length-1].id+1;

      //添加数据到数组中
      data.list.push(info);
      //将data转为json字符串保存到文件中 同时设置缩进2个字符
      data = JSON.stringify(data,null,2);
      writeData(data,()=>{
        //设置响应码
        res.statusCode = 302;
        //设置响应头
        res.setHeader('location','/index');
        //设置响应结束标志
        res.end();
      });
    });
 
  },
  //处理post添加的属性
  addPost(req, res) {
    //post方式添加 
    // 1- 获取前端表单提交的数据 get  post  
    // 2- 将数据添加到数据库中(data.json) 
    //         先读取data.json中数据 
    //         转数组 
    //         向数组中添加新数据
    //         在将数组转回json字符串
    //         将字符串写入到data.json 

    //准备一个空对象
    let str = "";
    //给req注册data事件,只要上传数据,data就会触发,chunk表示每次post发送的数据模块
    req.on('data',(chunk)=>{
      str += chunk;
    })

    //当数据发送完成完成后触发end事件
    req.on('end',()=>{
      //通过querystring的parse的方法,将post上传的数据转换为对象
      info = querystring.parse(str)
      //打印输出这个对象
      console.log(info)
      readData(data =>{

        //给info添加id
        info.id = data.list[data.list.length-1].id+1;
        //将info添加到数组中
        data.list.push(info);
        data = JSON.stringify(data,null,2)
        //将data写入到data.json文件中
        writeData(data,()=>{
          //设置响应码
          res.statusCode = 302;
          //设置响应头
          res.setHeader('location','/index');
          //设置响应结束标志
          res.end();
        });
      });
      
    });
  },
  //处理获取不到文件的方法
  notFind(req, res) {
    //响应结束标志
    res.end('404');
  }

}

//封装读取的函数
function readData(callback) {

  fs.readFile(path.join(__dirname,'data','data.json'),'utf-8',(err,data)=>{
    if(err){
      return console.log('读取文件失败',err)
    }
    //将json字符串转为对象
    data = JSON.parse(data);
    //如果传入回调函数,则调用回调函数,否则不调用
    callback && callback(data);
  });
}

//封装写入的函数
function writeData(data,callback) {
  fs.writeFile(path.join(__dirname,'data','data.json'),data,err=>{
    if(err){
      return console.log('写入文件失败',err)
    }
    callback && callback(data);
  });
  
}

认识express

什么叫express

基于 Node.js 平台,快速、开放、极简的 web 开发框架

如何使用express

基于安装完express之后使用!!!

安装命令: npm i express

1.导入express

const express = require('require');

2.创建服务器

const app = express();

3.监听请求事件

//引入express
const express = require('express');

//创建服务器
const app = express();


//监听请求
app.get('/index',(req,res)=>{
  console.log(req.url)
  console.log(req.method)
  console.log(req.query)

  res.send('get请求完成');
});


// 监听post请求
app.post('/index',(req,res)=>{
  console.log(req.url)
  console.log(req.method)
  console.log(req.body)
  
  res.send('POST请求完成');
});

//监听任意类型
app.all('/index',(req,res)=>{

  console.log(req.url)
  console.log(req.method)
  console.log(req.body)
  
  res.send('all请求完成');

});

//使用中间件监听
app.use((req,res)=>{
  console.log(req.url)
  console.log(req.method)
  console.log(req.body)
  
  res.send('任意请求完成');

})


//监听端口
app.listen(9998,()=>{
  console.log('http://localhost:9998 服务器已启动')
});

4.监听端口号

app.listen(9998,()=>{
    console.log('http://localhost:9998/index 服务器已启动')
});
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容