模块查找原则
模块分为:核心模块、第三方模块和自定义模块
核心模块查找原则:到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的导出项呢
初始化指向
赋值的指向
hackerNews2.2模块化实现
模块化示例图
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 服务器已启动')
});