模块化与内置模块-手写第一个web服务器程序-node.js初级(二)

     为什么要进行模块化:

        进行模块化主要是为了更好的维护我们的代码,我们把很多函数分组,分别放到不同的文件里面,一个js文件就是一个模块。

        这样能够提升代码的可维护性,也可以直接在自己的项目里引用其他的模块,就像Node内置的模块和其他来自第三方的模块

        重点:方便项目的开发和维护

        模块的规范:

        每一个模块的作用域是私有的,内部定义的变量或者函数,只在当前的文件中可以使用

        如果别人需要使用我们模块里面的东西,那么我们需要进行暴露引用才行

        1、自己编写的模块,由于模块的作用域是私有的,默认情况下,外部文件是无法使用的;如果要给外部文件使用,需要导出exports或者module.exports。导出方式为对象

        2、如果别人要使用某一个模块,则需要先引入该模块,使用require引入,然后用一个变量来接收导入的对象

        导出数据方式一:

        exports.num =num;

        exports.sum=sum;

        exports.Animal=Animal;

        导出数据方式二:

  module.exports={

        num,

        sun,

        Animal

}

          导入数据

const m1 = require("./modules/m1.js");

        模块里面的this指向问题:

        exports实际上是module.exports的引用,

        这么说,在文件里面,this代表当前的这个模块,也就是exports对象。

console.log(exports);   //{}
console.log(module.exports);  //{}
console.log(exports === module.exports);  //true  exports实际上是module.exports的引用
console.log('this', this); // this {}
console.log(this === exports);// true   
console.log(global === this );   //false    this不指向全局对象

        node的常用内置模块:

                一般项目中的模块分三种,nodejs内置模块、自己书写的模块和第三方模块

                常用的内置模块有一下几个:

        1、fs:文件操作

        2、http:网络操作

        3、path:路径操作

        4、querystring:查询参数解析

        5、url:url解析

             path内置模块:

const path = require("path");

console.log(__dirname); // 当前执行的文件绝对路径,不包含文件名

console.log(__filename);  // 当前执行的文件绝对路径,包含文件名

let extname = path.extname( __filename );   // 获取扩展名(后缀名)

let baseName = path.basename( __filename );  // 获取文件名(包含后缀名)

let dirname = path.dirname(__filename);   //获取目录(路径)

let parse = path.parse(__filename);  //获取路径字符串的对象
//parse对象包含上面所有的属性


//路径的拼接操作 join

let fullPath1 = path.join('path.js');

// fullPath1 = path.join(__dirname,'path.js'); //带目录

// fullPath1 = path.join(__dirname,'a','path.js'); //带多级目录

//带多级目录是最常使用的方式

        Buffer数据类型:

        js语言本身只有字符串数据类型,没有二进制数据类型。但是在处理文件流的时候,必须使用到二进制数据。所以在node里面,定义了一个Buffer类,该类用来创建一个专门存放二进制数据的缓存区。Buffer类似于一个整数型数组。

let buf1 = Buffer.from([97, 98, 99]);  //根据一个数组创建 Buffer 对象
console.log(buf1);  //<Buffer 61 62 63> 以16进制存在buffer对象中

let buf2 = Buffer.from("nodejs");   //根据一个字符串创建 Buffer 对象
console.log(buf2);

let buf3 = Buffer.alloc(10);   // 创建了可以存放10个字符的buffer对象
buf3.write("abc");  //按照ASCII表的值,转16进制,存在buffer中

//如果需要看到Buffer里面真正存储的数据时,需要用toString()才能展现出来
//Buffer主要原理是按照将要存储的数据转成16进制

         fs文件系统模块:

        同步读取:

        读取文件的时候,要等文件读取完毕之后,才会执行后面的代码。

const fs = require("fs");
const path = require("path");
let pathName = path.join(__dirname, 'hello.txt');

//同步读取
const content = fs.readFileSync(pathName, "utf-8");
console.log(content);

        异步读取://用的最多

        不用等待文件读取完毕就会执行后面的代码

        在读取文件的时候,需要传递一个回调函数,当读取完毕后,回调函数就执行,读取后面的数据。

        具体异步相关可以看我之前写的文章。

const fs = require("fs");
const path = require("path");

let pathName = path.join(__dirname, "hello2.txt");



fs.readFile(pathName, "utf-8",(error, data)=>{

    // console.log(error);
    // console.log(data);

   	if(error){
        console.log(error);
        return
    }

    console.log(data);
});

        异步写入:

const fs = require("fs");
const path = require("path");

let pathName = path.join(__dirname, "hello.txt");




fs.writeFile(pathName, "hello_write111", "utf-8",(error)=>{
    console.log("error");
    console.log("写完啦");
});

        fs的其他常用方法:

const fs = require("fs");



fs.renameSync(旧文件名, 新文件名);   //修改文件名
fs.readdirSync(__dirname);    //读取当前路径下的文件名列表

let str = "hello";
str.endsWith("he");   //true
str.startsWith("go");  //false
str.substring(2,4) //ll 左闭右开区间
str.substring(2) //llo  下标为2取到结束

        http模块:

           http核心模块的使用分四个步骤:

        1、导入http模块

        2、定义服务器程序端口

        3、创建服务器对象

        4、调用服务器的监听方法,让服务器监听浏览器请求

// 1、导入http模块
const http = require("http");

// 2、定义服务器程序端口
const port = 8080;

// 3、创建服务器对象
const server = http.createServer((request, response)=>{
    response.setHeader("Content-type","text/html;charset=utf-8");//如果需要解决中文乱码,需遵循http协议
    response.write("hello nodejs");  // 书写响应体内容
    response.end()   //发生响应到浏览器  当我们修改代码后,需要重新执行该文件,重启服务
});

// 4、调用服务器的监听方法,让服务器监听浏览器请求
server.listen(port,(error)=>{
    console.log(error);
    console.log(`server is running at port ${port}`);
});

        要获取请求的一些信息时:

const url = require("url");


const server = http.createServer((request, response)=>{

let requestUrl = request.url;  // 获取本次请求的资源路径

let method = request.method;  // 获取本次请求的方式

//当存在 post 提交数据 data 事件立马执行,postData就是提交过来的数据对象
    request.on('data',(postData) => {   // 获取post请求的请求参数
        console.log(postData.toString());
    });

response.write("hello nodejs");  // 书写响应体内容

response.end()   //发生响应到浏览器  当我们修改代码后,需要重新执行该文件,重启服务

});

        手写一个web服务器:

const http = require("http");
const fs = require("fs");
const path = require("path");


const server = http.createServer((request, response)=>{

    let requestUrl = request.url;
    console.log(requestUrl);
    if(requestUrl==="/" || requestUrl==="/index.html"){
        let content = fs.readFileSync(path.join(__dirname,"assets","html","index.html"));
        response.end(content)
    }
    else if(requestUrl==="/login.html"){
        let content = fs.readFileSync(path.join(__dirname,"assets","html","login.html"));
        response.end(content)
    }
    else if(requestUrl.indexOf(".css") > -1){
        let content = fs.readFileSync(path.join(__dirname,"assets","css",requestUrl));
        response.end(content)
    }
    else if(requestUrl.indexOf(".js") > -1){
        let content = fs.readFileSync(path.join(__dirname,"assets","js",requestUrl));
        response.end(content)
    }
    else{
        response.end("404 NOt Fround:找不到该页面")
    }

});


const port = 8080;

server.listen(port,(error)=>{
    console.log(error);
    console.log(`server is running at port ${port}`);

});




        目前来说,对于刚刚接触后端的小白来说,只能以这种较复杂的方式手写一个web服务器,在后面会学习espress框架,学习完后,代码将十分简洁,敬请期待!!!

猜你喜欢

转载自blog.csdn.net/qq_53087870/article/details/120128607