NodeJS的使用與NPM包管理器詳解
第1章 NodeJS
如果你是一個前端程序員,你不懂得像PHP、Python或Ruby等動態(tài)編程語言,然后你想創(chuàng)建自己的服務,那么Node.js是一個非常好的選擇。如果你熟悉Javascript,那么你將會很容易的學會Node.js。
1.1 NodeJS簡介
Node.js 是一個基于 Chrome V8 JavaScript 引擎 構建的開源、跨平臺運行時環(huán)境。V8 引擎是即 Google Chrome 的核心。這使 Node.js 的性能非常出色。V8引擎允許開發(fā)者使用 JavaScript 編寫服務器端代碼,而不是僅僅局限于瀏覽器中的前端開發(fā)。
Node.js 是運行在服務端的 JavaScript,是一個事件驅動I/O服務端JavaScript環(huán)境,基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度非???,性能非常好。
NodeJS官網(wǎng):https://nodejs.org/zh-cn
1.2 NodeJS下載
打開官網(wǎng)中的下載頁面,選擇一個合適的版本下載安裝包,然后雙擊安裝:
安裝過程:點擊下一步…下一步…默認安裝即可。
NodeJS歷史版本下載:https://nodejs.org/dist/
安裝完畢后,打開cmd窗口,輸入node -v查看node的版本。
1.3 Node基礎入門
1.3.1 控制臺輸出
我們現(xiàn)在做個最簡單的小例子,演示如何在控制臺輸出,創(chuàng)建文本文件demo01.js,代碼內容:
var a=1; var b=2; console.log(a+b);
我們在命令提示符下輸入命令
node demo01.js
1.3.2 使用函數(shù)
創(chuàng)建文本文件demo02.js
function add(a,b){ return a+b; } var c=add(100,200); console.log(c);
命令提示符輸入命令
node demo2.js
運行后看到輸出結果為300
1.4 NodeJS模塊化編程
模塊是Node.js 應用程序的基本組成部分,文件和模塊是一一對應的。換言之,一個 Node.js 文件就是一個模塊,這個文件可能是JavaScript 代碼、JSON 或者編譯過的C/C++擴展。
將一個復雜的程序文件依據(jù)一定規(guī)則(規(guī)范)拆分成多個文件的過程稱之為模塊化,其中拆分出的每個文件就是一個模塊 ,模塊的內部數(shù)據(jù)是私有的,不過模塊可以暴露內部數(shù)據(jù)以便其他模塊使用。
創(chuàng)建文本文件demo03_01.js
exports.add=function (a,b){ return a+b; }
創(chuàng)建文本文件demo03_2.js
// 導入demo03_1模塊,類似于Java中的對象 var demo= require('./demo03_01'); // 通過"對象名"調用方法 console.log(demo.add(400,600));
我們在命令提示符下輸入命令
node demo03_02.js
結果為1000
1.5 NodeJS內置模塊
Node.js 作為一個 JavaScript 的運行環(huán)境,其官方提供了非常多的的內置模塊,這些內置模塊就和Java中的核心API一樣,為NodeJS提供了很多基礎功能,我們可以通過require()將這些模塊導入到當前的JS文件中。
- fs:文件系統(tǒng)模塊。
- fs.writeFile(file, data[, options], callback):文件寫入
- fs.readFile(path[, options], callback):讀取文件
- fs.unlink(path, callback):刪除文件
- fs.mkdir(path[, options], callback):創(chuàng)建文件夾
使用示例:
// 導入fs模塊 const fs = require('fs'); fs.writeFile('./test01.txt', '學而時習之,不亦說乎', err => { //如果寫入失敗,則回調函數(shù)調用時,會傳入錯誤對象,如寫入成功,會傳入 null if (err) { console.log(err); return; } console.log('寫入成功'); });
1.5.1 fs模塊
fs模塊是nodejs中關于文件操作的模塊。
語法:
- fs.writeFile(file, data[, options], callback):文件寫入
- file 文件名
- data 待寫入的數(shù)據(jù)
- options 選項設置 (可選)
- callback 寫入回調
使用示例:
// 導入fs模塊 const fs = require('fs'); var str = "北冥有魚,其名為鯤。鯤之大,不知其幾千里也。" fs.writeFile('./test01.txt', str, err => { //如果寫入失敗,則回調函數(shù)調用時,會傳入錯誤對象,如寫入成功,會傳入 null if (err) { console.log(err); return; } console.log('寫入成功'); });
- fs.readFile(path[, options], callback):讀取文件
- path 文件路徑
- options 選項配置
- callback 回調函數(shù)
使用示例:
//導入 fs 模塊 const fs = require('fs'); // 讀取的是字節(jié) fs.readFile('./test01.txt', (err, data) => { if(err) throw err; console.log(data); }); // 安裝編碼來讀取 fs.readFile('./test02.txt', 'utf-8',(err, data) => { if(err) throw err; console.log(data); });
- fs.unlink(path, callback):刪除文件
- path 文件路徑
- callback 操作后的回調
const fs = require('fs'); fs.unlink('./test01.txt', err => { if(err) throw err; console.log('刪除成功'); });
- fs.mkdir(path[, options], callback):創(chuàng)建文件夾
- path 文件夾路徑
- options 選項配置( 可選 )
- callback 操作后的回調
使用示例:
const fs = require('fs'); // 創(chuàng)建文件夾 fs.mkdir('./a1', err => { if(err) throw err; console.log('創(chuàng)建成功'); }); //遞歸創(chuàng)建 fs.mkdir('./aa/b1/c1', {recursive: true}, err => { if(err) throw err; console.log('遞歸創(chuàng)建成功'); });
- fs.rmdir(path[, options], callback):刪除文件夾
- path:文件夾路徑
- options:選項配置( 可選 )
- callback:操作后的回調
使用示例:
const fs = require('fs'); //刪除文件夾 fs.rmdir('./a1', err => { if(err) throw err; console.log('刪除成功'); }); //遞歸刪除文件夾 fs.rmdir('./aa', {recursive: true}, err => { if(err) { console.log(err); } console.log('遞歸刪除') });
1.5.2 http模塊
http模塊是nodejs中有關于http協(xié)議的模塊。
(1)創(chuàng)建HTTP服務:
// 1. 導入http模塊 const http = require('http'); /** * 2. 創(chuàng)建http服務 * request:請求對象 * response:響應對象 */ const server = http.createServer((request, response) => { response.end('Hello HTTP server'); }); // 3. 監(jiān)聽端口, 啟動服務 server.listen(8000, () => { console.log('服務已經啟動, 端口 9000 監(jiān)聽中...'); });
打開瀏覽器,訪問:http://localhost:8000
(2)request對象
常用方法及屬性:
含義 | 語法 |
---|---|
請求方式 | request.method |
協(xié)議和版本 | request.httpVersion |
請求路徑 | request.url |
URL 路徑 | require(‘url’).parse(request.url).pathname |
URL 查詢字符串 | require(‘url’).parse(request.url).query |
請求頭 | request.headers |
請求體 | request.on(‘data’, function(chunk){}) request.on(‘end’, function(){}); |
使用示例:
// 1、引入http模塊 const http = require("http"); const url = require('url') // 2、建立服務 const server = http.createServer((request, response) => { // 設置響應類型 response.setHeader("Content-Type", "text/html;charset=utf-8") // 獲取完整的請求路徑(帶請求參數(shù)) var requestUrl =url.parse(request.url).pathname; // 獲取查詢字符串 var params = url.parse(request.url).query; response.write(`<hr> 請求方式: ${request.method}`); response.write(`<hr> 協(xié)議和版本: ${request.httpVersion}`); response.write(`<hr> 請求路徑: ${request.url}`); response.write(`<hr> URL 路徑: ${requestUrl}`); response.write(`<hr> URL 查詢字符串: ${params}`); response.write(`<hr> 請求頭: ${JSON.stringify(request.headers)}`); response.write("name:" + params.name); if (request.url == "/register" && request.method == "GET") { response.end("<hr> welcome to register..."); } else if (request.url == "/login" && request.method == "GET") { response.end("<hr> welcome to login..."); } else { response.end("<h1>404 Not Found</h1>") } }) // 3、監(jiān)聽端口 server.listen(8000, () => { console.log('服務啟動中....'); })
打開瀏覽器,訪問:http://localhost:8000/register?username=xiaohui
(3)response對象
常用方法及屬性:
作用 | 語法 |
---|---|
設置響應狀態(tài)碼 | response.statusCode |
設置響應狀態(tài)描述 | response.statusMessage |
設置響應頭信息 | response.setHeader(‘頭名’, ‘頭值’) |
設置響應體 | response.write(‘xx’) response.end(‘xxx’) |
使用示例:
require('http').createServer((request, response) => { //獲取請求的方法已經路徑 let {url, method} = request; // 設置響應類型 response.setHeader("content-Type", "text/html") if (method == "GET" && url == "/index.html") { // 通過fs模塊讀取文件(同步讀取) let data = require('fs').readFileSync('./index.html'); response.statusCode = 200; response.end(data); } else { let data = require('fs').readFileSync('./404.html'); response.statusCode = 404; response.end(data); } }).listen(8000, () => { console.log('8000端口正在啟動中....'); })
訪問:http://localhost:8000/index.html
1.6 NPM包管理工具
npm全稱Node Package Manager,他是node包管理和分發(fā)工具。我們可以把NPM理解為java中的Maven。我們通過npm可以很方便地下載js庫,管理前端工程。最近版本的node.js已經集成了npm工具,在命令提示符輸npm -v 可查看當前npm版本。
NPM官網(wǎng):https://www.npmjs.com/
1.6.1 修改npm鏡像
NPM官方的管理的包都是從 http://npmjs.com下載的,但是這個網(wǎng)站在國內速度比較慢。這里推薦使用淘寶 NPM 鏡像 ,淘寶 NPM 鏡像是一個完整 npmjs.com 鏡像。
設置鏡像地址:
#經過下面的配置,以后所有的 npm install 都會經過淘寶的鏡像地址下載 npm config set registry https://registry.npmmirror.com #查看npm配置信息 npm config list # 查看鏡像源 npm config get registry
1.6.2 相關命令
命令 | 介紹 |
---|---|
npm init | 初始化工程 |
npm init -y | 可以跳過向導,快速初始化工程 |
npm install | 簡寫npm i,自動下載package.json中dependencies中全部的依賴。 |
npm install 包名 | 簡寫npm i 包名,下載指定包 |
npm install --save 包名 | 簡寫npm i -S 包名,下載并保存依賴項(package.json中dependencies) 5.0.0版本之后的npm會自動保存到dependencies |
npm uninstall 包名 | 簡寫npm un 包名,只刪除,如果有依賴項會依然保存 |
npm uninstall --save 包名 | 簡寫npm un -S 包名,刪除的同時也會將依賴信息刪除 |
npm help | 查看使用幫助 |
npm 命令 --help | 查看對應命令的使用幫助,例如我忘記uninstall的簡寫,那么我可以輸入npm uninstall --help |
1.6.3 初始化工程
使用npm init命令可以把當前文件夾初始化成一個“包”,即一個標準的nodejs工程
建立一個空文件夾,在命令提示符進入該文件夾 執(zhí)行命令初始化
npm init npm init -y # 全面使用默認值來初始化項目
按照提示輸入相關信息,如果是用默認值則直接回車即可。
C:\Users\Admin\Desktop\dfxt\dfxt_day02\web\NodeJSDemo\demo04_npm>npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help init` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (demo04_npm) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to C:\Users\Admin\Desktop\dfxt\dfxt_day02\web\NodeJSDemo\demo04_npm\package.json: { "name": "demo04_npm", # 項目名稱 "version": "1.0.0", # 項目版本號 "description": "", # 項目描述 "main": "index.js", # 入口文件 "scripts": { # 腳本 "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", # 作者 "license": "ISC" # 認證信息 } Is this OK? (yes) yes
npm init 命令的作用是將文件夾初始化為一個“包”,創(chuàng)建 package.json 文件,執(zhí)行完npm init后會生成package.json文件,這個是包的配置文件,相當于maven的pom.xml,我們之后也可以根據(jù)需要進行修改。
1)安裝鏡像
install命令用于安裝某個模塊,如果我們想安裝jquery模塊,輸出命令如下:
# 下載最新版本的jquery npm install jquery
在該目錄下已經出現(xiàn)了一個node_modules
文件夾和package-lock.json
文件。
- node_modules文件夾:用于存放下載的js庫(相當于maven的本地倉庫)。
- package-lock.json文件:確定當前安裝的包的依賴,以便后續(xù)重新安裝的時候生成相同的依賴,而忽略項目開發(fā)過程中有些依賴已經發(fā)生的更新。
我們再打開package.json文件,發(fā)現(xiàn)剛才下載的jquery已經添加到依賴列表中了,依賴包會被添加到dependencies節(jié)點下,類似maven中的<dependencies>
標簽。
安裝時想指定特定的版本:
npm install jquery@3.2.1
查看package.json的依賴:
"dependencies": { "jquery": "^3.2.1" }
2)版本號說明
- 指定版本:比如3.2.1,遵循“大版本.次要版本.小版本”的格式規(guī)定,安裝時只安裝指定版本。
- 波浪號指定版本:比如~3.2.1,表示安裝3.2.x的最新版本(不低于3.2.1),但是不安裝3.3.x,也就是說安裝時不改變大版本號和次要版本號。
- 插入號指定版本:比如ˆ3.2.1,表示安裝3.x.x的最新版本(不低于3.2.1),但是不安裝2.x.x,也就是說安裝時不改變大版本號。需要注意的是,如果大版本號為0,比如^0.2.1,則插入號的行為與波浪號相同,這是因為此時處于開發(fā)階段,即使是次要版本號變動,也可能帶來程序的不兼容。
- latest:安裝最新版本。比如:
npm install jquery@latest
。需要注意,“最新版本”指的是latest標簽指向的版本,而latest通常是主版本的最新穩(wěn)定版,但不一定是最高的版本號,因為可能有預發(fā)布版本存在。例如,如果一個包的版本是1.2.3,然后發(fā)布了2.0.0-beta,這時候latest可能仍然指向1.2.3,直到2.0.0正式發(fā)布。
npm安裝依賴說明:
場景 | 實際安裝版本 |
---|---|
npm install vue | 安裝 latest 標簽對應的版本(如 Vue 3.4.21) |
npm install vue@next | 安裝 next 標簽對應的版本(如 Vue 3.4.21-beta) |
npm install vue@3.2.0 | 安裝精確指定版本(3.2.0) |
npm ci | 嚴格按 package-lock.json 安裝,確保環(huán)境一致性 |
3)全局安裝
在 npm 中,-g
是 --global
的縮寫,表示全局安裝。它的作用是將一個包(package)安裝到系統(tǒng)的全局環(huán)境中,而不是當前項目的本地目錄。全局安裝后的包可以在系統(tǒng)的任何目錄下通過命令行直接使用。
全局安裝適用于需要跨項目使用的命令行工具或全局工具。例如:vue-cli
(Vue 腳手架)、create-react-app
(React 腳手架)、nodemon
(自動重啟 Node 服務)等。
全局安裝的路徑:
- Windows:
C:\Users\<用戶名>\AppData\Roaming\npm\node_modules
- macOS/Linux:
/usr/local/lib/node_modules
安裝與卸載全局包:
npm install -g @vue/cli # 全局安裝 Vue CLI(跨項目使用) npm uninstall -g @vue/cli # 卸載全局的 Vue CLI
4)運行依賴和開發(fā)依賴
我們使用npm install <packageName>
就能在線下載依賴到本地的node_modules目錄,但我們項目打包時通常不會打包項目的node_modules以減輕項目大小。當項目發(fā)送給了團隊的其他成員時只有源代碼而沒有項目所需的依賴,此時項目是無法運行的。
因此我們安裝某個依賴時,除了下載依賴項到本地的node_modules目錄外,還應該記錄當前項目的依賴項配置,這樣就算其他人獲得到了項目源代碼也可以按照依賴項配置來下載當前項目所需依賴。
在安裝(npm install xxx)某個依賴項時,可以通過配置--save
或--save-dev
來將該依賴項記錄下來:
- –save 等同于 -S (常用,可保存在package.json文件中):依賴項信息將加入到dependencies中,表示是生產階段的依賴,也就是項目運行時的依賴,就是程序上線后仍然需要依賴。
- –save-dev 等同于 -D:依賴項信息將加入到devDependencies,表示是開發(fā)階段的依賴,就是我們在開發(fā)過程中需要的依賴,只在開發(fā)階段起作用。
Tips:從npm 5.0.0版本開始,默認行為改變了?,F(xiàn)在當運行npm install xxx時,npm會自動將包添加到dependencies中,相當于之前需要–save的效果。
如下:
{ // jquery是開發(fā)依賴 "devDependencies": { "jquery": "^3.7.1" }, // bootstrap是生產依賴 "dependencies": { "bootstrap": "^5.3.5" } }
項目運行時必須依賴的包(無論是本地開發(fā)、生產環(huán)境還是其他環(huán)境),例如一些框架或常用庫,如:JQuery、Bootstrap、Vue、axios等依賴,如果缺少這些依賴,代碼將無法運行,這些依賴就應該是dependencies;
一些僅在開發(fā)階段需要的依賴,生產環(huán)境不需要。例如一些構建、轉碼、測試工具等,如webpack、babel、eslint、jest等,這些依賴投入到生產環(huán)境中就再也不需要了,這些依賴就應該是devDependencies;
1.6.5 package和package-lock文件 1)package文件:
package.json定義了這個項目所需要的各種模塊,以及項目的配置信息,包括名稱、版本、許可證、依賴模塊等元數(shù)據(jù)。
當執(zhí)行 npm install 的時候,node 會先從 package.json 文件中讀取所有 dependencies 信息,然后根據(jù) dependencies 中的信息與 node_modules 中的模塊進行對比,沒有的直接下載,已有的檢查更新。另外,package.json 文件只記錄你通過 npm install 方式安裝的模塊信息,而這些模塊所依賴的其他子模塊的信息不會記錄。
2)package-lock文件:
package.json文件中保存著項目的依賴以及這些依賴的版本信息,但是這些依賴的版本并非是一個固定的,而是可以隨著時間的流逝(例如該依賴發(fā)布了新版本)自動更新的。因此,同一個package.json在不同時間點執(zhí)行npm install
可能會導致項目實際使用的依賴版本不同。
如項目中JQuery依賴為ˆ3.2.1
,當前該依賴最新發(fā)布版本為3.5.1
,執(zhí)行npm install
命令后將3.5.1版本的JQuery下載到了項目中。四個月后JQuery官方對其進行更新,當前最新版本為3.7.1,此時從新執(zhí)行該項目的``npm install`將會安裝3.7.1版本的JQuery。
可以看到,同一個項目,不同時間點來執(zhí)行安裝命令會導致項目的依賴版本不一樣。package-lock.json文件正是來解決這個問題的。
package-lock.json 文件會保存 node_modules 中所有包的信息,包括精確版本 version 和下載地址 resolved 以及依賴關系 dependencies 等,用以記錄當前狀態(tài)下實際安裝的各個模塊的具體來源和版本號。這樣 npm install 時速度就會提升。
當項目中已有package-lock.json 文件,在安裝項目依賴時,將以該文件為主進行解析安裝指定版本依賴包,而不是使用 package.json 來解析和安裝模塊。因為 package.json 指定的版本不夠具體,而package-lock 為每個模塊及其每個依賴項指定了版本,位置和完整性哈希,所以它每次的安裝都是相同的。
package-lock.json 文件主要作用有以下兩點:
1)當刪除 node_module 目錄時,想通過 npm install 恢復所有包時,提升下載速度。
2)鎖定版本號,防止自動升級新版本。
項目中存在了package-lock.json當下載依賴時會以該文件中鎖定的版本來下載,但有時我們也希望更新一下項目依賴,此時可以執(zhí)行npm update
來更新項目的依賴版本,并且更新package-lock.json鎖定的版本。
一般來說前端工程完畢后是不會將node_modules文件夾打包到項目中的(精簡項目),當項目發(fā)布到互聯(lián)網(wǎng)時,用戶需要自行執(zhí)行npm install來根據(jù)package.json或package-lock.json文件來下載依賴。如果項目中沒有package-lock.json可以使用如下命令來構建一個package-lock.json:
npm install --package-lock-only
到此這篇關于NodeJS的使用與NPM包管理器詳解的文章就介紹到這了,更多相關nodejs與npm包管理器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Nodejs監(jiān)控事件循環(huán)異常示例詳解
這篇文章主要給大家介紹了關于Nodejs監(jiān)控事件循環(huán)異常的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Nodejs具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-09-09