模块化的使用和认识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 服务器已启动')
});

你可能感兴趣的:(模块化的使用和认识express)