1. 程式人生 > >Node.js_2.包、NPM、Node.js核心模組

Node.js_2.包、NPM、Node.js核心模組

包、NPM、Node.js核心模組

1 包和NPM

1.1 包

1.1.1 CommonJS規範

最初運行於客戶端控制頁面的互動與行為;
沒有模組系統、沒有標準庫、沒有標準介面、沒有包管理系統;
CommonJS是JS為在更廣範圍地應用而定義的API標準和規範
Node.js實現了CommonJS規範,實現了其定義的API以及模組和包的編寫使用和維護規範

1.1.2 包

package:在模組基礎上更深一步的抽象;類似於C的函式庫或者Java的類庫,將獨立的功能封裝起來,用於釋出、更新、依賴管理和版本控制
Node.js根據CommonJS規範實現包機制:包是一個目錄,包含任意的js檔案,包含一個名為package.json的包說明檔案
目錄式自定義模組就是最簡單的包

1.1.3 包的結構

1.package.json檔案應該存在於包頂級目錄下;
2.二進位制檔案在bin目錄下;
3.js程式碼在lib目錄下;
4.文件在doc目錄下;
5.單元測試在test目錄下
Node.js中require()函式不僅可引入檔案模組還可以引入符合規範的包;

在呼叫包時,首先檢查package.json檔案的main欄位指定入口檔案;如果不存在則嘗試尋找index.js作為包的入口
package.json檔案,所有內容是一個物件:
{
“main”: “hello.js”
//json:所有屬性必須加雙引號;值如果是數字可以不加,字串一定要加雙引號;
}

如果require(’’)選擇使用不帶路徑的目錄模組,會自動到當前目錄資料夾node_modules中查詢目錄模組,如果沒有則到上一級尋找直至頂層目錄;

1.2 NPM(node package manage)

1.2.1 包管理器

官網:www.npmjs.com,包管理器Node.js提供的包管理工具,用於下載、安裝、升級和刪除包或者釋出並維護;
使用步驟:
1.通過命令列進入安裝目錄;
2. npm init建立一個package.json檔案
3. npm install 包名 --save
–cnpm 表示下載地址是國內的npm
使用npm init可以對之後每次安裝的包記錄進行儲存,當需要拷貝這些包只需要拷貝.json檔案,在進入該目錄後直接輸入npm install,會自動根據複製的.json檔案下載包

1.2.2 常用包

常用包

2 核心模組

2.1 工具模組

  1. Querystring
    該模組提供處理url中的查詢字串部分的相關操作
    const querystring = require(‘querystring’);
    //從查詢字串中解析資料物件
    querystring.parse(qs)//qs是需要解析的查詢字串
    //將資料物件轉換為查詢字串引數形式
    querystring.stringify(data)//data是定義的資料物件

  2. URL
    URL模組提供處理URL中不同部分的相關操作
    const url = require(‘url’);
    //解析URL各組成部分
    url.parse(requestUrl);//requestUrl是string型別的url
    //將查詢字串解析為物件
    urlObj = url.parse(requestUrl, true)
    //將物件格式化
    url.format(urlObj)

  3. Buffer緩衝區
    Buffer是全域性物件global下的一個物件。
    建立 var buf= Buffer.alloc(length, [value]);
    寫入 buf.write(),預設顯示Unicode碼,使用toString()檢視原始的值

  4. Path

  5. Util

2.2 FS模組

2.2.1 FS模組概述

Node.js核心模組,提供檔案讀寫、更名、刪除、遍歷目錄等操作;
操作有同步、非同步兩種形式:I/O操作密集的應用中使用非同步呼叫方式來避免阻塞整個處理程序;
非同步非阻塞:使用回撥函式獲取結果
同步阻塞:通過函式返回值獲取結果

常用class:
fs.Stats:檔案或目錄的統計資訊描述物件
fs.ReadStream:stream.Readable介面的實現物件
fs.WriteStream:stream.Writable介面的實現物件
fs.FSWatcher:可用於監視檔案修改的檔案監視器物件

常用方法:
fs.mkdir():建立目錄
fs.rmdir():刪除目錄
fs.readdir():讀取目錄
fs.readFile():讀取檔案內容
fs.writeFile():向檔案中寫出內容
fs.appendFile():向檔案中追加內容
fs.unlink():刪除檔案
fs.rename():重新命名檔案
上述非同步函式中,只有fs.stat()、fs.readdir()、fs.readFile()需要在回撥函式中除了err宣告返回內容,列印對應同步函式直接返回內容
fs.existsSync():判斷檔案是否存在,只有同步函式

2.2.2 檔案資訊統計

非同步fs.stat()和同步fs.statSync()用於返回檔案或目錄的統計資訊物件(fs.Stats型別);
相同功能的同步函式與非同步函式相比不需要回調函式callback
stats.isFile():是否為檔案;
stats.isDirectory():是否為目錄;
上述兩個方法都是返回結果stats的成員,所以需要在回撥函式中使用

fs.stat()用來檢視檔案狀態,err儲存錯誤資訊,stats儲存檔案資訊
//注意路徑從命令列處開始尋找

fs.stat('./a.txt', (err,stats)=> {
	if(err) {
		throw error;//直接return的話,不會丟擲異常
	}else {
		console.log(stats);
	}
});

2.2.3 操作目錄

fs.mkdir(path[, mode], callback):建立指定目錄
fs.rmdir(path, callback):刪除指定目錄
fs.readdir(path[, options], callback):讀取目錄下內容

const path = './mypackage';
fs.stat(path, (err,stats)=> {
	if(err) {
		fs.mkdir(path,(err)=>{
		});
	}else {
		fs.readdir(path, function(err, list) {
			console.log(list);
		})
	}
});
fs.rmdir('./mypackage', (err)=>{});

2.2.4 讀寫檔案(非同步操作有可能未寫入已讀寫)

可以一次性讀寫資料量不是很大的檔案的全部內容,返回的資料是buffer形式

fs.readFile(file[, options], callback):讀取檔案內容

const src = './htdocs/index.html';
fs.readFile(src, (err,data)=>{
	if (err) throw err;
	//讀取到的資料儲存在Buffer例項中
	console.log(data.toString());
})

寫檔案時,若目標檔案不存在,writeFile方法會自動建立該檔案;若目標檔案存在,則該方法會覆蓋原有內容

fs.writeFile(file, data[, options], callback):

const dest = './backup/index.html';
var data = 'Some Data';
fs.writeFile(dest, data, (err)=> {
	if (err) throw err;
	console.log(..);
})

向檔案追加內容,如果目標檔案不存在,appendFile方法自動建立該檔案,否則在原有內容後面追加新內容

fs.appendFile(file, data[, options], callback):

fs.appendFile(dest, data, (err)=>{
	if (err) throw err;
});

//刪除檔案
fs.unlink('./data.txt', (err)=>{
  console.log(err);
});

2.3 HTTP模組

2.3.1 HTTP協議

瀏覽器與Web伺服器之間的通訊訊息格式遵守HTTP協議,是典型的基於"請求-響應"模型的協議。當客戶端發出請求訊息,伺服器才會給出響應訊息;

請求訊息:由客戶端構建傳送給Web伺服器,有四部分構成:

  1. General通用頭資訊:
    1)Request URL:請求的URL,要向服務端請求哪個檔案;
    2)Request Method:請求方法描述了當前請求的目的
    ~ GET:表示客戶端想獲取伺服器上指定資源;
    ~ POST:表示客戶端想向伺服器傳遞並儲存資料
    ~ PUT:表示客戶端想向伺服器傳遞並更新資料
    ~ DELETE:表示客戶端想從伺服器刪除指定資料
    只有POST、PUT請求才有請求主體;
    HTML表單只能使用發起GET和POST請求;XHR物件可以發起任意HTTP請求

    3)Status Code:響應狀態碼,響應起始行中的響應狀態碼用於標識響應訊息的狀態,有五類可能:
    3.1)1xx::請求-響應繼續進行
    3.2)2xx:成功響應
    3.3)3xx:響應重定向到其他地址
    3.4)4xx:客戶端請求錯誤
    3.5)5xx:伺服器端執行錯誤
    4)Remote Address:請求的遠端伺服器的IP地址和埠
  2. 響應頭資訊:
    Connection:keep-alive;連線方式:持續連線
    Content-Type:text-html;響應的檔案型別
    Content-Encoding:響應的檔案壓縮形式
    Transfer-Encoding:響應時的傳輸方式,chunked(分段傳輸)
    Location:響應時跳轉的URL,對應狀態碼為3xx系列
  3. 請求頭資訊
    Accept:客戶端接收的檔案型別
    Accept-Encoding:客戶端接收的檔案壓縮形式
    Accept-Language:客戶端接收的語言型別
    Connection:客戶端和伺服器的連線方式,keep-alive持續連線
  4. 請求主體:
    可有可無,客戶端向伺服器傳遞資料

2.3.2 HTTP模組概述

Node.js內建HTTP模組提供底層的方法,用於建立使用HTTP協議的客戶端或伺服器端應用
Web客戶端:建立併發起請求訊息,等待並解析響應訊息;
Web伺服器:接收並解析請求訊息,構建併發送響應訊息;

2.3.3 HTTP客戶端

http.request是客戶端工具,用於向HTTP伺服器發起請求,返回http.ClientRequest物件;
模擬瀏覽器:http.get(url, callback)
get 請求的方法
url 請求的網址
callback 回撥函式,用來獲取伺服器端的響應
res 響應的物件
res.statusCode 獲取響應的狀態碼
res.on(‘data’, (buf)=>{ })
使用事件來獲取伺服器端響應的資料
buf是伺服器端響應的資料,格式為buffer資料


//建立HTTP請求訊息物件
var request = http.request( options, [callback])
//建立HTTP GET請求訊息物件
var request = http.get( options, [callback])
//引數options指定請求訊息起始行和請求訊息頭部

var options = {hostname:'www.baidu.com', port:80, path:'/'};
var req = http.get(options, function(res) {
	console.log(res.statusCode);//狀態碼
	console.log(JSON.stringify(res.headers));//響應頭
	res.setEncoding('utf8');
	//事件
	res.on('data',function(chunk) {
		console.log(chunk.toString);//響應內容
	});
});
req.setTImeout(3000, ()=>{
	req.abort();//取消請求
});
req.on('error', (err)=>{console.log(err)});//發生錯誤

ClientRequest常用方法:
write(chunk):向伺服器追加請求主體資料
end(chunk):提交請求訊息主體結束
setTimeout(timeout, fn):設定請求訊息超時時間
abort():終止請求

ClientRequest常用事件:
response:接收響應訊息
abort:請求終止事件
error:請求發生錯誤


2.3.4 HTTP伺服器

http.server是基於事件的HTTP伺服器,核心由Node.js底層C++實現,介面由JS封裝,兼顧高效能與易用性:
用於建立底層Web伺服器應用,以接收客戶端請求訊息並返回響應訊息提供Web內容服務,返回http.Server型別物件,以描述當前建立Web伺服器
//建立基於HTTP協議的Web伺服器

var server = http.createServer();//建立伺服器
server.listen(3000, ()=>{//分配埠
	console.log("server1 created!");
});

//接收瀏覽器的請求,是一個事件,一旦有請求,自動執行
server.on('request', (req, res)=>{
	//req->請求物件
	console.log(req.url);//請求的路徑
	console.log(req.method);//直接通過位址列預設使用get方法
	console.log(req.headers);//請求的頭資訊
	
	//res->響應物件
	res.write();//響應內容為文字形式
	res.writeHead(302, {});//設定響應的狀態碼和響應的頭資訊;跳轉需要設定Location屬性
	res.end();//響應結束,結束以後才會將響應物件傳送給客戶端
});

http.server常用方法:
listen(port, [host]):監聽指定服務埠
close():停止伺服器的執行
setTimeout(timeout, fn):設定伺服器響應訊息超時

http.Server常用事件:
connection:出現客戶端連線
request:接收請求訊息
close:伺服器停止事件
error:響應過程發生錯誤

createServer的使用:
http.createServer();//使用引數為回撥函式,否則監聽方法建立物件的request事件

//建立伺服器
var server = http.createServer((req, res)=>{
	//解析請求訊息、輸出響應訊息
});
//使用埠
server.listen(80);
server.on('request', (request, response)=>{});

Server物件的response事件回撥函式中
第一個引數是IncomingMessage物件,封裝客戶端提交的請求訊息資料;
第二個引數是ServerResponse物件,用於構建向客戶端輸出的響應訊息資料

server.on('request', (request, response)=>{
	console.log(request.method, request.headers);
	response.writeHead(200, 'OK', {
		'content-type': 'text/html;charset=utf-8'
	});
	response.write('...');
});
server.listen(8080);//使用埠
server.on('error', (error)=>{console.log(err)});