node.js零基礎詳細教程(2):模塊化、fs文件操作模塊、http創建服務模塊


第二章  建議學習時間4小時  課程共10章

學習方式:詳細閱讀,並手動實現相關代碼

學習目標:此教程將教會大家 安裝Node、搭建服務器、express、mysql、mongodb、編寫后台業務邏輯、編寫接口,最后完成一個完整的項目后台,預計共10天課程。

 

模塊兒化


 為什么需要模塊兒化?

我們以前的常規js代碼中,我們為了重用一些js代碼,是將js方法封裝起來,放到js文件中,然后在HTML頁面中引入js,就可以在頁面中使用這些方法了。

當這種直接引入和調用的方式存在一些不友好的地方,比如,1、如果兩個js中有重名的方法,就會產生覆蓋。2、如果某個js需要調用另一個js里的方法,那么就對js引入的順序有限制,就比如我們使用jQuery的時候一般在js的最前面引入。

這樣就有了模塊化的需求:將獨立功能的js封裝成一個模塊,避免重名並且不必考慮引入順序問題。

  • Node.js遵守CommonJS規范(這個只是一種模塊兒化的代碼編寫規范,具體的細節可自行搜索了解,接下來我們寫具體的代碼)

那么怎么來實現模塊兒化呢?

我們在自己的某個文件夾中(示例為nodeTest) , 先創建文件夾 module, 在里面創建 module01.js  module02.js  test.js,創建后的目錄結構如下:

 

注:上圖那個文件結構知識示例,可以命令行 在對應目錄 運行  tree /f  打印

 

模塊兒化的實現需要三步:

1、編寫模塊並暴露接口

在module01.js中寫入下面的代碼,編寫了兩個方法,並使用node自帶的 module對象向外暴露接口。

(代碼解釋:module對象是Node自帶的模塊兒化對象,該對象下默認有一個空對象 -- exports ,我們將需要暴露的對象直接賦值給exports就向外暴露了接口,下一步將講解如何使用接口)

function fn01(){  //編寫一個方法 fn01
    console.log("module01-fn01");
}
function fn02(){  //編寫一個方法 fn02
    console.log("module01-fn02");
}

//暴露接口
module.exports = {
    "fn01":fn01,
    "fn02":fn02
}

 

2、使用接口

在test.js中寫入 如下代碼

var module01 = require("./module01.js"); //使用 require引入模塊,並申明一個變量來接收接口暴露的對象

module01.fn01(); //訪問接口暴露的方法

 解釋:(1)使用node自帶方法 require引入模塊,格式  require("文件路徑"),【這里的  ./  表示當前路徑 】, ()然后我們申明了一個變量 module01來接收引入模塊暴露的對象,這個對象就是我們上一步中給exports賦值的那個對象,關系如下:

module01 == {
    "fn01":fn01,
    "fn02":fn02
}

既然我們使用 module01接收到了這個對象,我們就可以調用 里面的方法或屬性了。 使用 module01.fn01(),就可以執行 module01.js 中的 fn01方法。

 

3、運行看效果

使用node 運行test.js的時候,就可以看到fn01方法執行 打印的 "module01-fn01";

 

 

 

多個模塊的引用

我們上一步只引入了module01.js ,這一步我們引入多個模塊

1、我們先將 module02.js 也寫成接口,代碼和module.js基本一致,只是 打印的 內容 改為了  "module02-fn01"

function fn01(){  //編寫一個方法 fn01
    console.log("module02-fn01");
}
function fn02(){  //編寫一個方法 fn02
    console.log("module02-fn02");
}

//暴露接口
module.exports = {
    "fn01":fn01,
    "fn02":fn02
}

2、我們在 test.js中引入模塊 

將原來的test.js代碼修改成如下代碼:

var module01 = require("./module01.js"); //module01.js 的暴露對象 使用 變量 module01接收
var module02 = require("./module02.js"); //module02.js 的暴露對象 使用 變量 module02接收

module01.fn01(); //訪問module01.js的方法
module02.fn02(); //訪問module02.js的方法

3、執行test.js

即可看到兩個模塊的方法都被調用了,這里我們可以看到,就算模塊中使用了同樣的方法,在使用的時候,由於定義了不同的變量來接收,也不會互相影響,而且我們要使用哪個模塊就直接引用就可以,這就是模塊兒化的優勢。

 

模塊兒化暴露接口的另一種方法

直接將需要暴露的方法以屬性 附加到 exports對象上。作用和上面的方法是一樣的,我們來修改一下module02.js的代碼

function fn01(){  //編寫一個方法 fn01
    console.log("module02-fn01");
}
function fn02(){  //編寫一個方法 fn02
    console.log("module02-fn02");
}

//暴露接口
exports.fn01 = fn01;
exports.fn02 = fn02;

此時運行test.js,效果和上一步是一樣的。

 

 

fs文件操作模塊


讀取文件

node自帶文件操作模塊 fs,使用時只需要直接引入即可

首先創建文件 fs01.js  a.txt文件

編輯 a.txt。任意寫入點文字  (注意 編碼格式 修改為 utf-8,如果是默認格式,中文文字讀取的時候會是亂碼)

注:怎么將a.txt,修改為utf-8格式

新建的txt文檔默認是ANSI格式,只需將txt另存為,另存的時候修改右下角的格式設置即可。

 

編輯 fs01.js,寫入一下代碼(代碼解釋在運行效果的后面)

var fs = require("fs"); //node 內置模塊可直接引入  fs:文件系統操作模塊

fs.readFile("./a.txt","utf-8",function(err,data){  //讀取文件
    console.log(err,data);
});

運行,即可看到  下圖的顯示,第一個箭頭null表示 沒有出錯, 第二個箭頭表示讀取的a.txt內部內容

 

解釋:  第一行代碼我們引入了 node的自帶模塊  fs (文件操作模塊)

第二行代碼調用了 fs模塊下的讀取文件方法  readFile,  內部傳入三個參數  ,1、讀取的文件路徑 , 2、編碼格式, 3、回調函數,回調函數中有兩個參數  err 和 data ,  err表示錯誤信息,當文件讀取錯誤的時候會賦值錯誤提示,data表示讀取的文件內容。

 

一般情況下,如果讀取出錯我們需要拋出異常終止程序。所以需要將代碼修改如下

var fs = require("fs"); //node 內置模塊可直接引入  fs:文件系統操作模塊

fs.readFile("./a.txt","utf-8",function(err,data){  //讀取文件
    if(err) throw err;
    console.log(err,data);
    //讀取的后續操作可寫在這里
});

 

寫入文件  

使用 writeFile方法

將上一步讀取的數據寫入b.txt文件中

說明:后續我都直接修改fs01.js的代碼來演示,大家可以自己創建新的js文件來寫代碼和執行。

將 fs01.js代碼修改如下(中間添加寫入文件的代碼):

var fs = require("fs"); //node 內置模塊可直接引入  fs:文件系統操作模塊

fs.readFile("./a.txt","utf-8",function(err,data){  //讀取文件
    if(err) throw err;
    //讀取的后續操作可寫在這里
    fs.writeFile("./b.txt",data,function(err){  //寫入文件
        if(err) throw err;
    })
});

 

解釋:writeFile方法有三個參數,1、寫入的文件路徑(如果沒有此文件,node會自動創建一個b.txt),2、需要寫入的數據(這里我們將從a.txt中讀取的數據 傳給 b.txt) , 3、回調函數,只有一個參數,當出現寫入錯誤的時候,會有錯誤提示 err

執行fs01.js即可看到當前文件夾中新增加了一個b.txt。且內部寫入了內容

 

 

writeFile是將內容替換掉,如果想要追加寫入,可以使用appendFile方法

我們修改 fs01.js的里的寫入方法為 appendFile

 

然后多次執行 fs01.js

然后打開 b.txt,就可以看到多次寫入了內容

 

刪除文件 ,使用 unlink方法

var fs = require("fs"); //node 內置模塊可直接引入  fs:文件系統操作模塊

fs.unlink("./b.txt",function(err){  //刪除文件
    if(err) throw err;
})

unlink方法有兩個參數,1、要刪除的路徑,2、回調函數,如果出現錯誤,會有err提示

修改 fs01.js內容為上面代碼,然后執行 fs01.js,就可以看到 b.txt被刪除了

 

創建文件夾

使用  mkdir  方法  ,該方法有兩個參數 1、文件夾名,2、回調函數,如果出現錯誤,會有err提示

修改 fs01.js內容為下面代碼,然后執行 fs01.js,就可以看到 在當前文件夾中創建了 名為 c 的文件夾

var fs = require("fs"); //node 內置模塊可直接引入  fs:文件系統操作模塊

fs.mkdir("c",function(err){  //創建 c 文件
    if(err) throw err;
})

 

 

修改文件名/文件夾名

使用 remane,該方法有兩個參數 1、需要修改的文件名(當前目錄下),2、新的文件名,3、回調函數,如果出現錯誤,會有err提示

修改 fs01.js內容為下面代碼,然后執行 fs01.js,就可以看到 在當前文件夾中 文件夾 c  名字被修改為了 d

var fs = require("fs"); //node 內置模塊可直接引入  fs:文件系統操作模塊

fs.rename("c","d",function(err){  //將c 文件夾名字 改為  d
    if(err) throw err;
})

 

 

修改 fs01.js內容為下面代碼,然后執行 fs01.js,就可以看到 在當前文件夾中 文件 a.txt  名字被修改為了 d.txt

var fs = require("fs"); //node 內置模塊可直接引入  fs:文件系統操作模塊

fs.rename("a.txt","d.txt",function(err){  //將a.txt 改為  d.txt
    if(err) throw err;
})

 

 

 

http模塊,創建后台服務器


 

 node自帶創建服務的模塊 http,使用時只需要直接引入即可

 首先創建文件 http01.js ,然后添加如下代碼

var http = require("http");

http.createServer(function(request,response){
    
    console.log("request going"); //當瀏覽器訪問的時候,在控制台回打印此消息
    response.end("haha");//表示請求結束,將結果返回給瀏覽器

}).listen(3000);

說明:

首先引入  http 模塊 ,

然后調用  createServer方法創建服務,里面只有一個參數(回調函數:表示請求發生的時候需要執行的代碼【回到函數有兩個參數,1、請求信息,2、相應信息】),

最后需要添加端口監聽  listen(自定義端口號,這里我們常規使用3000),

運行 http01.js, 如果沒有報錯,就表示 服務已經啟動,然后在瀏覽器中輸入  http://localhost:3000/  就可以訪問服務器了,會顯示 返回的 "hehe" 文字;

注意:啟動服務后,再修改了js文件以后,不會直接更新到頁面,需要命令行按 ctrl+c 結束運行,  再重新運行 該js 后  ,再刷新 瀏覽器,才能看到效果。

當訪問以后,再看控制台,就可以看到打印的信息

 

 

讀取一個文件並傳輸給頁面

在當前文件夾,創建a.txt文件,寫入一段文字

 

然后修改http01.js的代碼為如下代碼,然后運行,即可將讀取的a.txt的數據寫入頁面

var http = require("http");//引入http模塊
var fs = require("fs"); //引入fs模塊

http.createServer(function(request,response){
    
    fs.readFile("./a.txt","utf-8",function(err,data){  //讀取文件
       if(err) throw err;
       response.end(data);//表示請求結束,將結果返回給瀏覽器
   });

}).listen(3000);

 

 

 

 

 好,今天就講這么多,明天將講解:npm包管理、git github的使用。

 

 

關注公眾號,博客更新即可收到推送

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM