1.Node.js 概述
1.1 Node.js 不是一門編程語言秃症,它是一個(gè)執(zhí)行 JavaScript 代碼的工具。工具是指可以安裝在計(jì)算機(jī)操作系統(tǒng)之上的軟件变姨。
1.2 瀏覽器和 Node.js 都可以運(yùn)行 JavaScript 族扰,因?yàn)樗鼈兌純?nèi)置了 JavaScript V8 Engine ,它可以將 JavaScript 代碼編譯為計(jì)算機(jī)能夠識(shí)別的機(jī)器碼定欧。
1.3 瀏覽器中運(yùn)行的 JavaScript 和 node.js 中運(yùn)行的 JavaScript:
- 在內(nèi)置了 JavaScript V8 Engine 以后實(shí)際上只能執(zhí)行 ECMAScript 渔呵,就是語言中的語法部分;
- 瀏覽器為了能夠讓 JavaScript 操作瀏覽器窗口以及 HTML 文檔砍鸠,所以在 JavaScript V8 Engine 中添加了控制它們的 API 厘肮,就是 DOM 和 BOM ,所以JavaScript 在瀏覽器中運(yùn)行時(shí)是可以控制瀏覽器窗口對(duì)象和 DOM 文檔對(duì)象的睦番;
- 和瀏覽器不同类茂,在 Node.js 中是沒有 DOM 和 BOM 的,所以在 Node.js 中不能執(zhí)行和它們相關(guān)的代碼托嚣,比如 window.alert() 或者 document.getElementbyId() 巩检。DOM 和 BOM 是瀏覽器環(huán)境中特有的。
- 在 Node.js 中示启,作者向其添加了很多系統(tǒng)級(jí)別的 API 兢哭,比如對(duì)操作系統(tǒng)中的文件和文件夾進(jìn)行操作。獲取操作系統(tǒng)信息夫嗓,比如系統(tǒng)內(nèi)存總量是多少迟螺,系統(tǒng)臨時(shí)目錄在哪,對(duì)系統(tǒng)的進(jìn)程操作等等舍咖。
- JavaScript 運(yùn)行在瀏覽器中控制的是瀏覽器窗口和 DOM 文檔矩父。
- JavaScript 運(yùn)行在 Node.js 中控制的操作系統(tǒng)級(jí)別的內(nèi)容。
- 瀏覽器中的 JavaScript 不能控制系統(tǒng)級(jí)別的 API:瀏覽器是運(yùn)行在用戶的操作系統(tǒng)中的排霉,如果能控控制系統(tǒng)級(jí)別的 API 就會(huì)存在安全的問題窍株; Node.js 是運(yùn)行在遠(yuǎn)程的服務(wù)器中的,訪問的是服務(wù)器系統(tǒng) API,不存在這方面的的安全問題球订。
- Node.js 能夠做的:我們通常使用它來構(gòu)建服務(wù)器端應(yīng)用和創(chuàng)建前端工程化工具后裸;
- JavaScript 運(yùn)行在瀏覽器中我們就叫它客戶端 JavaScript;
- JavaScript 運(yùn)行在 Node.js 中我們就叫它服務(wù)器端 JavaScript
2冒滩、系統(tǒng)環(huán)境變量
- 系統(tǒng)環(huán)境變量是指在操作系統(tǒng)級(jí)別上定義的變量微驶,變量中儲(chǔ)存了程序運(yùn)行時(shí)所需要的參數(shù)
- 比如在使用 webpack 構(gòu)建前端應(yīng)用時(shí)就使用到了系統(tǒng)環(huán)境變量,因?yàn)?webpack 需要根據(jù)系統(tǒng)環(huán)境變量判斷當(dāng)前為開發(fā)環(huán)境還是生產(chǎn)環(huán)境开睡,根據(jù)環(huán)境決定如何構(gòu)建應(yīng)用
在開發(fā)環(huán)境的操作系統(tǒng)中定義 NODE——ENV 變量因苹,值為 development ,在生產(chǎn)環(huán)境的操作系統(tǒng)中定義 NODE_EVN 變量士八,值為 production 。 - webpack 在運(yùn)行時(shí)通過 process.env.NODE_EVN 獲取變量的值梁呈,從而得出當(dāng)前代碼的運(yùn)行環(huán)境是什么婚度。
- 環(huán)境變量 PATH:系統(tǒng)環(huán)境變量 PATH 中存儲(chǔ)的都是應(yīng)用程序路徑。當(dāng)要求系統(tǒng)運(yùn)行某一個(gè)應(yīng)用程序又沒有告訴它完整程序路徑時(shí)官卡,此時(shí)操作系統(tǒng)會(huì)先在當(dāng)前文件夾中查找應(yīng)用程序蝗茁,如果查找不到就會(huì)去系統(tǒng)環(huán)境變量 PATH 中指定的路徑中查找。
3寻咒、安裝 Node.js
- 官網(wǎng)下載: https://nodejs.org/zh-cn/
- 有兩個(gè)版本哮翘。LTS:長(zhǎng)期支持版(穩(wěn)定版)可以運(yùn)行在生產(chǎn)環(huán)境中;Current: 最新版(預(yù)覽版)不建議運(yùn)行在生產(chǎn)環(huán)境中毛秘,因?yàn)榭赡苡?BUG
- 安裝過程中可能出現(xiàn)的兩個(gè)問題:
在運(yùn)行 node 命令時(shí)提示“不是內(nèi)部或外部命令饭寺,也不是可運(yùn)行的程序或批處理文件”:
將 Node 應(yīng)用程序目錄添加到系統(tǒng)環(huán)境變量中,然后重新啟動(dòng)命令行工具再次執(zhí)行 node 命令 - 安裝 Node 的過程中出現(xiàn)代碼為 2502 和 2503 的錯(cuò)誤
1.通過管理員權(quán)限打開命令行工具叫挟;
2.切換到 node 安裝包所在的目錄艰匙;
3.通過 mesiexec/package node-v10.15.0-x64.mis 運(yùn)行 node 應(yīng)用程序安裝包(node-v10.15.0-x64.mis 安裝包的名字)
4、全局變量
- 在 Node.js 環(huán)境中是沒有 window 的抹恳,所以 window 對(duì)象自然是未定義的
- 在 Node.js 環(huán)境中全局對(duì)象為 global 员凝,在 global 對(duì)象中會(huì)存在一些和 window 對(duì)象名字相同且作用相同的方法
- 在 Node.js 環(huán)境中聲明的變量不會(huì)被添加到全局對(duì)象中,變量聲明后只能在當(dāng)前文件中使用
- process 對(duì)象是一個(gè)全局變量奋献,提供了有關(guān)當(dāng)前 Node.js 進(jìn)程的信息并對(duì)其進(jìn)行控制健霹。
// process是全局變量,使用時(shí)瓶蚂,無需引入糖埋,引入也不報(bào)錯(cuò),但是沒有必須引入
// const process= require("process");
console.log(process)
//輸出當(dāng)前版本
console.log(process.version) //v14.16.0
//輸出操作系統(tǒng)架構(gòu)
console.log(process.arch) // x64
//輸出操作系統(tǒng)平臺(tái)
console.log(process.platform) // win32
//環(huán)境變量
console.log(process.env)
//自定義環(huán)境變量
process.env.NODE_ENV = 'develop'
console.log(process.env.NODE_ENV) // develop
//獲取進(jìn)程編號(hào)
console.log(process.pid) //(系統(tǒng)分配窃这,每次執(zhí)行不一樣)
//殺死進(jìn)程
process.kill() //參數(shù):進(jìn)程編號(hào)
5阶捆、模塊成員導(dǎo)出與導(dǎo)入
- 模塊概述:在 Node.js 環(huán)境中,默認(rèn)就支持模塊系統(tǒng),該模塊系統(tǒng)遵循 CommonJS 規(guī)范洒试;一個(gè) JavaScript 文件就是一個(gè)模塊倍奢,在模塊文件中定義的變量和函數(shù)默認(rèn)只能在模塊文件內(nèi)部使用,如果需要在其他文件中使用垒棋,必須顯式聲明將其進(jìn)行導(dǎo)出
- 模塊成員導(dǎo)出:
在每一個(gè)模塊文件中卒煞,都會(huì)存在一個(gè) module 對(duì)象,即模塊對(duì)象叼架。在模塊對(duì)象中保存了和當(dāng)前模塊相關(guān)信息畔裕;
在模塊對(duì)象中有一個(gè)屬性 exports ,它的值是一個(gè)對(duì)象乖订,模塊內(nèi)部需要被導(dǎo)出的成員都應(yīng)該存儲(chǔ)到這個(gè)對(duì)象中 - 模塊成員導(dǎo)入:
在其他文件中通過 require 方法引入模塊扮饶,require 方法的返回值就是對(duì)應(yīng)模塊的 module.exports 對(duì)象 - 在導(dǎo)入模塊時(shí),模塊文件后綴 .js 可以省略乍构,文件路徑不可省略
- require 方法屬于同步導(dǎo)入模塊甜无,模塊導(dǎo)入后可以立即使用
- 通過 require 方法引入模塊時(shí)會(huì)執(zhí)行該模塊中的代碼
- 在導(dǎo)入其他模塊時(shí),建議使用 const 關(guān)鍵字聲明常量哥遮,防止模塊被重置
- 有時(shí)在一個(gè)模塊中只會(huì)導(dǎo)出一個(gè)成員岂丘,為方便其他模塊使用,導(dǎo)出時(shí)可以直接把值賦給 module.exports;導(dǎo)入直接獲取眠饮,不需要打點(diǎn)調(diào)用了
6奥帘、 Module Wrapper Function 模塊包裝函數(shù)
- 在模塊文件執(zhí)行之前,模塊文件中的代碼會(huì)被包裹在模塊包裝函數(shù)中仪召,這樣每個(gè)模塊文件中的代碼就都擁有了自己的作用域寨蹋,所以在模塊外部就不能訪問模塊內(nèi)部的成員了。
(function (exports, require, module, __filename, __dirname) {
// entire module code lives here
})() - module 和 require 是模塊內(nèi)部成員扔茅,不是全局對(duì)象 global 下面的屬性
__filename : 當(dāng)前模塊文件名稱
__dirname :當(dāng)前文件所在路徑 - exports: 引用地址指向了 module.exports 對(duì)象的簡(jiǎn)寫形式
- 在導(dǎo)入模塊時(shí)最終導(dǎo)入的是 module.exports 對(duì)象钥庇,所以在使用 exports 對(duì)象添加導(dǎo)出成員時(shí)不能修改引用地址
7、Node.js 內(nèi)置模塊
在 Node.js 安裝完成后咖摹,會(huì)內(nèi)置一些非常有用的模塊
Path: 模塊內(nèi)提供了一些路徑操作相關(guān)的方法
// 引入
const path = require("path")
//獲取當(dāng)前文件所在的路徑
console.log(process.cwd())
console.log(__dirname)
//獲取當(dāng)前文件所在的路徑
console.log(process.cwd())
//獲取當(dāng)前文件所在的路徑
// dir = directory 目錄 C:\Users\ROG\Desktop\拉鉤教育\fed-e-task-base-03-01\code
console.log(__dirname)
//獲取當(dāng)前文件的完整路徑 C:\Users\ROG\Desktop\拉鉤教育\fed-e-task-base-03-01\code
console.log(__filename)
//獲取文件的擴(kuò)展名 .js
console.log(path.extname(__filename))
// 獲取路徑中的目錄部分 C:\Users\ROG\Desktop\拉鉤教育\fed-e-task-base-03-01\code
console.log(path.dirname(__filename))
//獲取路徑中的文件名 path.js
console.log(path.basename(__filename));
// 相當(dāng)于../
const t = path.join(__dirname, '..')
console.log(t) // C:\Users\ROG\Desktop\拉鉤教育\fed-e-task-base-03-01
//將多個(gè)路徑合并起來
const a = path.join("d:/",'a', 'b')
console.log(a) // d:\a\b
fs: 文件操作系統(tǒng)评姨,提供了操作文件的方法
// 文件寫入
const fs = require("fs");
fs.writeFile('./1.txt','我是寫入的內(nèi)容', (err)=>{
if(err){
throw err;
}
console.log("寫入成功")
});
// 文件讀取
var flieName = path.join(__dirname, './1.txt');
fs.readFile(flieName, (err, data)=>{
if(err) throw err;
//data是二進(jìn)制數(shù)據(jù),但是以16進(jìn)制數(shù)據(jù)輸出
console.log(data);
console.log(data.toString()) // 我是寫入的內(nèi)容
})
// 文件刪除
var flieName = path.join(__dirname, './1.txt');
fs.unlink(flieName, (err)=>{
if(err) throw err;
console.log("刪除成功")
})
//追加寫入
fs.appendFile(__dirname + '/2.txt', '曾經(jīng)有一首歌是這樣唱的', err => {
if(err) throw err;
console.log("追加成功")
})
//創(chuàng)建目錄
fs.mkdir('./a', err => {
if(err){
throw err;
}
console.log("success");
})
// 刪除目錄 rmdir 只能刪除空目錄
// 先刪除目錄下的普通文件萤晴,再通過rmdir刪除空目錄
fs.rmdir('./a', err => {
if (err) {
throw err;
}
console.log("刪除成功");
})
//重命名
fs.rename(__dirname + "/a1", __dirname + "/a11", err => {
if (err) {
throw err;
}
console.log("重命名成功");
});
// 寫文件
fs.readdir(__dirname, (err, data) => {
if(err) throw err;
console.log(data.length); //文件夾和文件都可以讀取出來
data.map((d)=>{
console.log(d);
fs.stat(__dirname + '/' + d, (err, stat) => {
if(err) throw err;
if(stat.isDirectory()){ //判斷是否是目錄
console.log("目錄:", d);
}else if(stat.isFile()){
console.log("文件:", d);
}
})
})
- http
const http = require("http")
/**
* 創(chuàng)建服務(wù)器
*/
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader("Content-type", "text/plain;charset=utf-8")
res.end("你好吐句,node.js")
})
/**
* 發(fā)布web服務(wù)
*/
const port = 3000;
const host = "localhost"
server.listen(port, host, ()=>{
console.log(`服務(wù)器運(yùn)行在htp://${host}:${port}`)
})
在引入內(nèi)置模塊時(shí),使用的是模塊的名字店读,前面不需要加任何路徑
8嗦枢、npm 概述
- Node.js 軟件包: 每一個(gè)基于 Node.js 平臺(tái)開發(fā)的應(yīng)用程序都是 Node.js 軟件包;
- 所有 Node.js 軟件包都被托管在 www.npmjs.com 中
- npm:Node Package Manager 屯断, Node.js 環(huán)境中的軟件包管理器文虏,隨 Node.js 一起被安裝侣诺;
- 它可以將 Node 軟件包添加到我們的應(yīng)用程序中并對(duì)齊進(jìn)行管理,比如下載氧秘,刪除年鸳,更新,查看版本等等丸相;
- 它沒有用戶界面搔确,需要在命令行工具中通過命令的方式使用,對(duì)應(yīng)的命令就是 npm 灭忠;
- NPM 和 Node 是兩個(gè)獨(dú)立的應(yīng)用程序膳算,只是被捆綁安裝了,可以通過版本號(hào)證明
9弛作、package.json
- Node.js 規(guī)定在每一個(gè)軟件包中都必須包含一個(gè)叫做 package.json 的文件涕蜂;
- 它是應(yīng)用程序的描述文件,包含的應(yīng)用程序相關(guān)的信息映琳,比如應(yīng)用名稱机隙,應(yīng)用版本,應(yīng)用作者等等刊头;
- 通過 package.json 文件可以方便管理應(yīng)用和發(fā)布應(yīng)用黍瞧; 創(chuàng)建 package.json 文件: npm init ;
- 快速創(chuàng)建 package.json 文件: npm init --yes
10诸尽、下載 Node.js 軟件包
- 在應(yīng)用程序的根目錄執(zhí)行命令原杂, npm install <pkg> 或者 npm i <pkg> 如:npm install lodash
- 軟件包下載完成后會(huì)發(fā)生三件事:
1.軟件包會(huì)被存儲(chǔ)在 node_modules 文件夾中,如果在應(yīng)用中不存在此文件夾您机, npm 會(huì)自動(dòng)創(chuàng)建
2.軟件包會(huì)被記錄在 package.json 文件中穿肄,包含軟件包的名字以及版本號(hào)
3.npm 會(huì)在應(yīng)用中創(chuàng)建 package-lock.json 文件,用于記錄元件包及軟件包的依賴包的下載地址及版本
11际看、使用 Node.js 軟件包
- 在引入第三方軟件包時(shí)咸产,在 require 方法中不需要加入路徑信息,只需要使用軟件包的名字即可仲闽,require 方法會(huì)自動(dòng)去 node_modules 文件夾中進(jìn)行查找
- 軟件包依賴問題說明:
1. 比如在我的應(yīng)用中要依賴 mongoose 軟件包脑溢,于是我下載了它,但是在 node_modules 文件夾中除了包含 mongoose 以外還多出了很多其他軟件包赖欣,為什么會(huì)多出這么多軟件包呢屑彻?
實(shí)際上它們又是 mongoose 依賴的軟件包。
2. 為什么 mongoose 依賴的軟件包不放在 mongoose 文件夾中呢顶吮?
在早期的 npm 版本中, 某個(gè)軟件包依賴的其他軟件包都會(huì)被放置在該軟件包內(nèi)部的node_modules 文件夾中社牲,但是這樣做存在兩個(gè)問題,第一個(gè)問題是很多軟件包都會(huì)有相同的依賴悴了,導(dǎo)致開發(fā)者在一個(gè)項(xiàng)目中會(huì)下載很多重復(fù)的軟件包搏恤,比如 A 依賴 X违寿,B 依賴 X,C 依賴 X熟空,在這種情況下 X 就會(huì)被重復(fù)下載三次藤巢。第二個(gè)問題是文件夾嵌套層次太深,導(dǎo)致文件夾在 windows系統(tǒng)中不能被直接刪除痛阻。比如 A 依賴 B, B 依賴 C, C 依賴 D ... , 就會(huì)發(fā)生文件夾依次嵌套的情況菌瘪。
3. 所有的軟件包都放置在 node_modules 文件夾中不會(huì)導(dǎo)致軟件包的版本沖突嗎?
在目前的 npm 版本中阱当,所有的軟件包都會(huì)被直接放置在應(yīng)用根目錄的 node_modules 文件夾中俏扩,這樣雖然解決了文件夾嵌套層次過深和重復(fù)下載軟件包的問題,但如果只這樣做肯定會(huì)導(dǎo)致軟件包版本沖突的問題弊添,如何解決呢录淡?
比如 A 依賴 X 的 1 版本,B 依賴 X 的 2 版本油坝,如果你先下載的是 A嫉戚,那么 A 依賴的 X 會(huì)被放置在根目錄的 node_modules 文件夾中, 當(dāng)下載 B 時(shí),由于在根目錄中已經(jīng)存在 X 并且版本不一致澈圈,那么 B 依賴的 X 就會(huì)被放置在 B 軟件包中的 node_module 文件夾中彬檀,通過此方式解決軟件包版本沖突的問題。
4. node_modules 文件夾中的軟件包都需要提交到 git 倉庫中嗎瞬女?
在 node_modules 文件夾中有很多軟件包窍帝,隨著應(yīng)用程序的增長(zhǎng),軟件包也會(huì)越來越多诽偷,甚至?xí)_(dá)到幾百兆坤学。當(dāng)我們將應(yīng)用提交到版本庫時(shí),我們不想提交它报慕,因?yàn)樗鼈儾皇俏覀儜?yīng)用中的源代碼深浮,而且由于碎文件比較多,其他人在檢出代碼時(shí)需要等待的時(shí)間會(huì)很久眠冈。當(dāng)其他人拿到應(yīng)用程序時(shí)沒有依賴軟件包應(yīng)用程序是運(yùn)行不起來的飞苇,如何解決呢?
實(shí)際上應(yīng)用程序依賴了哪些軟件包在 package.json 文件中都會(huì)有記錄,其他人可以通過 npm install 命令重新下載它們蜗顽。為了保持下載版本一直布卡,npm 還會(huì)根據(jù) package-lock.json 文件中的記錄的地址進(jìn)行下載。將應(yīng)用程序提交到版本庫之前诫舅,將 node_modules 文件夾添加到 .gitignore 文件中羽利。
12、語義版本控制
1.版本號(hào)規(guī)范: 2.3.4
2:添加新功能(破壞現(xiàn)有API)==> 2.2.4
3:添加新功能(不會(huì)破壞現(xiàn)有 API刊懈,在現(xiàn)有API 的基礎(chǔ)上進(jìn)行添加) ==> 2.4.4
4:用于修復(fù) bug ==> 2.3.5
2.版本號(hào)更新規(guī)范
^2.3.4:主要版本不變这弧,更新次要版本和補(bǔ)丁版本
~2.3.4:主要版本和次要版本不變娃闲,更新補(bǔ)丁版本
2.3.4:使用確切版本,即主要版本匾浪、次要版本皇帮、補(bǔ)丁版本固定
13、查看軟件包實(shí)際版本
- 在 node_module 文件夾中找到對(duì)應(yīng)的依賴軟件包蛋辈,找到它的package.json文件属拾,可以在這個(gè)文件中的 version 字段中找到它的具體版本
- 通過 npm list 命令查看所有依賴軟件包的具體版本,--depth 選項(xiàng)指定查看依賴包的層級(jí)
14冷溶、查看軟件包的元數(shù)據(jù)
- npm view mongoose
- npm view mongoose versions 查看具體的某一項(xiàng)的元數(shù)據(jù)
- npm view mongoose dist-tags dependencies 查看多個(gè)項(xiàng)渐白,空格分開
15、下載特定版本的軟件包
- npm i <pkg>@<version> npm i mongoose@2.4.2 lodash@4.7.0
- cat package.json npm list --depth 0
- 刪除軟件包
npm uninstall <pkg> npm uninstall mongoose npm un mongoose
16逞频、更新軟件包
- 通過 npm outdated 命令可以查看哪些軟件包已經(jīng)過期纯衍,對(duì)應(yīng)的新版本是什么
- 通過 npm update 更新過期的軟件包,更新操作遵循語義定義版本控制規(guī)則
17苗胀、項(xiàng)目依賴和開發(fā)依賴
- 項(xiàng)目依賴:無論在開發(fā)環(huán)境還是線上環(huán)境只要程序在運(yùn)行的過程中需要使用的軟件包就是項(xiàng)目依賴襟诸。比如 lodash, mongoose
- 開發(fā)依賴:在應(yīng)用開發(fā)階段使用,在生產(chǎn)環(huán)境中不需要使用的軟件包基协,比如 TypeScript 中的類型聲明文件
- 在 package.json 文件中歌亲,項(xiàng)目依賴和開發(fā)依賴要分別記錄,項(xiàng)目依賴被記錄在 dependencies 對(duì)象中澜驮,開發(fā)依賴都被記錄在 devDependencies 中陷揪,使開發(fā)者可以在不同的環(huán)境中下載不同的依賴軟件包
- 在下載開發(fā)依賴時(shí),要在命令的后面加上 --save-dev 選項(xiàng)或者 -D 選項(xiàng)泉唁。 npm i eslint -D
- 在開發(fā)環(huán)境中下載的所有依賴軟件包 : npm install
- 在生產(chǎn)環(huán)境中只下載項(xiàng)目依賴軟件包: npm install --prod
18鹅龄、全局安裝與本地安裝
- 本地安裝:將軟件包下載到應(yīng)用根目錄下的 node_modules 文件夾中揩慕,軟件包只能在當(dāng)前應(yīng)用中使用
- 全局安裝:將軟件包下載到操作系統(tǒng)的指定目錄中临谱,可以在任何應(yīng)用中使用
- 通過 -g 選項(xiàng)將軟件包安裝到全局: npm install <pkg> -g
- 查看全局軟件包安裝位置: npm root -g
- 刪除全局中的軟件包: npm un npm-check-updates -g
- 查看全局中安裝了哪些軟件包: npm list -g --depth 0
- 查看全局中有哪些過期軟件包: npm outdated -g
- nodemon :命令工具軟件包稿存,可以監(jiān)控文件變化,自動(dòng)重新執(zhí)行文件 npm install nodemon@2.0.7 -g
19、npm-check-updates 強(qiáng)制更新
- npm-check-updates 可以查看應(yīng)用中有哪些軟件包過期局雄,可以強(qiáng)制更新 package.json 文件中軟件包版本
1.將 npm-check-updates 安裝到全局: npm install npm-check-undates -g
2.查看過期軟件包: npm-check-updates
3.更新: package.json : ncu -u
4.安裝軟件包: npm i
5.檢測(cè): npm outdated 或 npm-check-updates
20、發(fā)布軟件包
- 注冊(cè) npm 賬號(hào) https://www.npmjs.com/ yao_xiao_yao
- 創(chuàng)建軟件包 npm init -y 生成package.json
- 創(chuàng)建模塊
- 登錄 npm (npm 鏡像地址必須為 npmjs.com) npm login
- 發(fā)布軟件包 npm publish
- 測(cè)試:在其他應(yīng)用中使用該軟件包渔工; npm install 包名
21畦贸、更新版本號(hào)
- 在軟件包的源代碼發(fā)生更改后,是不能直接發(fā)布的樟凄,應(yīng)該更新軟件包的版本號(hào)再進(jìn)行發(fā)布
- 更新主要版本號(hào): npm version major
- 更新次要版本號(hào): npm version minor
- 更新補(bǔ)丁版本號(hào): npm verison patch
22聘芜、撤銷已發(fā)布的軟件包
- 只有在發(fā)布軟件包的24小時(shí)內(nèi)才允許撤銷
- 軟件包撤銷后 24 小時(shí)以后才能重新發(fā)布
- 重新發(fā)布時(shí)需要修改包名稱和版本號(hào)
npm unpublish <pkg> --force
23、更改 npm 鏡像地址
- 由于 npmjs.com 是國外的網(wǎng)站缝龄,大多數(shù)的時(shí)候下載軟件包的速度比較慢汰现,可以通過配置的方法更改 npm 工具的下載地址
- 獲取 npm 配置 npm config list -l --json
-l 列表表示所有默認(rèn)配置選項(xiàng)
--json 以 json 格式顯示配置選項(xiàng) - 設(shè)置 npm 配置
獲取 npm 下載地址: npm config get registry
獲取 npm 用戶配置文件: npm config get userconfig - 更改 npm 鏡像地址
npm config set registry https://registry.npm.taobao.org
npm config set registry https://registry.npmjs.org
24挂谍、 npx 命令
- npx 是 npm 軟件包提供的命令,它是 Node.js 平臺(tái)下軟件包執(zhí)行器瞎饲。主要用途有兩個(gè)口叙,第一個(gè)是臨時(shí)安裝軟件包執(zhí)行后刪除它,第二個(gè)是執(zhí)行本地安裝的提供命令的軟件包
1.臨時(shí)安裝軟件包執(zhí)行后刪除軟件包
有些提供命令的軟件包使用的頻率并不高嗅战,比如 creat-react-app 腳手架工具妄田,我們不能臨時(shí)下載使用,然后刪除掉它驮捍。
npx create-react-app react-test
2.執(zhí)行本地安裝的軟件包
現(xiàn)在有兩個(gè)項(xiàng)目都依賴了某個(gè)命令工具軟件包疟呐,但是項(xiàng)目 A 依賴的是它的1版本,項(xiàng)目 B 版本依賴的是它的 2 版本东且,該軟件包可以在本地進(jìn)行安裝萨醒,在 A 項(xiàng)目中安裝它的 1 版本,在 B 項(xiàng)目中安裝它的 2 版本苇倡,在應(yīng)用中可以通過 npx 調(diào)用 node_modules 文件夾中安裝的命令工具
將所有軟件包安裝到應(yīng)用本地是現(xiàn)在最推薦的做法富纸,一是可以防止軟件包的版本沖突問題,二是其他開發(fā)者在恢復(fù)應(yīng)用依賴時(shí)可以回復(fù)全部依賴旨椒,因?yàn)檐浖惭b到本地后會(huì)被 package.json 文件記錄晓褪,其他開發(fā)者在運(yùn)行項(xiàng)目時(shí)不會(huì)因?yàn)槿鄙僖蕾嚩鴪?bào)錯(cuò)
25、配置入口文件的作用
- 應(yīng)用程序入口文件就是應(yīng)用程序執(zhí)行的起點(diǎn)综慎,就是啟動(dòng)應(yīng)用程序時(shí)執(zhí)行的文件
場(chǎng)景一:其他開發(fā)者拿到你的軟件包之后涣仿,通過該文件可以直到應(yīng)用的入口文件是誰,通過入口文件啟動(dòng)應(yīng)用
場(chǎng)景二:通過 node 應(yīng)用文件夾 命令啟動(dòng)應(yīng)用示惊。 node 命令執(zhí)行 package.json 文件中 main 選項(xiàng)指定的入口文件好港,如果沒有指定的入口文件,則執(zhí)行 index.js
26米罚、模塊查找規(guī)則
- 在指定了查找路徑的情況下: require("./server")
查找 server.js 钧汹; 查找 server.json ; 查找 server 文件夾录择,查看入口文件(package.json -> main) 拔莱; 查找 server 文件夾 中的 index.js 文件 - 在沒有指定查找路徑的情況下: require("server")
27、異步編程
- CPU 與 存儲(chǔ)器
- CPU 中央處理器隘竭,計(jì)算機(jī)核心部件塘秦,負(fù)責(zé)運(yùn)算和指令調(diào)用;開發(fā)者編寫的
- JavaScript 代碼在被編譯為機(jī)器碼以后就是通過CPU執(zhí)行的
存儲(chǔ)器:
內(nèi)存 用于臨時(shí)存儲(chǔ)數(shù)據(jù)动看,斷電后數(shù)據(jù)丟失尊剔,由于數(shù)據(jù)讀寫速度快,計(jì)算機(jī)中的應(yīng)用都是在內(nèi)存中運(yùn)行的菱皆;
磁盤 用于持久存儲(chǔ)數(shù)據(jù)须误,斷電后數(shù)據(jù)不丟失笔咽,內(nèi)部有磁頭依靠馬達(dá)轉(zhuǎn)動(dòng)在盤片上讀寫數(shù)據(jù),速度比內(nèi)存慢 - 計(jì)算機(jī)應(yīng)用程序在沒有運(yùn)行時(shí)是存儲(chǔ)在磁盤中的霹期,當(dāng)我們啟動(dòng)應(yīng)用程序后叶组,應(yīng)用程序會(huì)被加載到內(nèi)存中運(yùn)行,應(yīng)用程序中的指令會(huì)被中央處理器CPU來執(zhí)行
28历造、I/O
- I 就是 Input 表示輸入甩十, O 就是 Output 表示輸出, I/O操作就是輸入輸出操作
- 比如數(shù)據(jù)庫的讀寫操作就是I/O操作吭产,因?yàn)閿?shù)據(jù)庫文件是存儲(chǔ)在磁盤中的侣监,而我們編寫的程序是運(yùn)行在內(nèi)存中的,將內(nèi)存中的數(shù)據(jù)寫入數(shù)據(jù)庫對(duì)于內(nèi)存來說就是輸出臣淤,查詢數(shù)據(jù)庫中的數(shù)據(jù)就是將磁盤中的數(shù)據(jù)讀取到內(nèi)存中橄霉,對(duì)如內(nèi)存來說就是輸入
- I/O模型
1. CPU 等待I/O操作完成獲取到操作結(jié)構(gòu)后再去執(zhí)行其他命令,這是同步I/O操作(阻塞I/O)
2. CPU 不等待I/O操作完成邑蒋, CPU 在發(fā)出I/O 指令后姓蜂,內(nèi)存和磁盤開始工作,CPU繼續(xù)執(zhí)行其他命令医吊。當(dāng)I/O操作完成后再通知 CPU I/O操作的結(jié)果是什么钱慢。這是異步I/O操作(非阻塞I/O) - 同步I/O和異步I/O區(qū)別就是是否等待I/O結(jié)果
29、進(jìn)程和線程
- 每當(dāng)我們運(yùn)行應(yīng)用程序中卿堂,操作系統(tǒng)會(huì)創(chuàng)建該應(yīng)用程序的實(shí)例對(duì)象束莫,該實(shí)例對(duì)象就是應(yīng)用程序的進(jìn)程,操作系統(tǒng)會(huì)操作系統(tǒng)會(huì)按照進(jìn)程為單位為應(yīng)用程序分配資源草描,比如內(nèi)存览绿,這樣程序才能夠在計(jì)算機(jī)的操作系統(tǒng)中運(yùn)行起來。
- 線程被包裹在進(jìn)程之中穗慕,是進(jìn)程中的實(shí)際運(yùn)作單位饿敲,一條線程指的就是進(jìn)程中的一個(gè)單一順序的控制流。也就是說揍诽,應(yīng)用程序要做的事情都存儲(chǔ)在線程之中诀蓉±跏可以這樣認(rèn)為暑脆,一條線程就是一個(gè)待辦列表,供 CPU 執(zhí)行狐肢。
30添吗、回調(diào)函數(shù)
- 回調(diào)函數(shù)是指通過函數(shù)參數(shù)的方式將一個(gè)函數(shù)傳遞到另一個(gè)函數(shù)中,參數(shù)函數(shù)就是回調(diào)函數(shù)
- 在主函數(shù)中調(diào)用回調(diào)函數(shù)時(shí)份名,可以為回調(diào)函數(shù)傳遞參數(shù)
- 在異步編程中碟联,異步 API 執(zhí)行的結(jié)果就是通過回調(diào)函數(shù)傳遞參數(shù)的方式傳遞到上層代碼中的妓美。
- 回調(diào)地獄:回調(diào)地獄是回調(diào)函數(shù)多層嵌套導(dǎo)致代碼難以維護(hù)的問題。
基于回調(diào)函數(shù)的異步編程一不小心就會(huì)產(chǎn)生回調(diào)地獄的問題鲤孵。
31壶栋、基于 Promise 的異步編程
- Promise 是 JavaScript 中異步編程解決方案,可以解決回調(diào)函數(shù)方案中的回調(diào)地獄問題普监」笫裕可以將 Promise 理解為容器,用于包裹異步 API 的容器凯正,當(dāng)容器中的異步 API 執(zhí)行完成后毙玻,Promise 允許我們?cè)谌萜鞯耐饷娅@取異步 API 的執(zhí)行結(jié)果,從而避免回調(diào)函數(shù)嵌套廊散。
- Promise 翻譯為承若桑滩,表示它承若幫我們做一些事情,既然它承若了它就要去做允睹,做就會(huì)有一個(gè)過程运准,就會(huì)有一個(gè)結(jié)果,結(jié)果要么是成功要么是失敗缭受。
- 所以在 Promise 中有三種狀態(tài), 分別為等待(pending)戳吝,成功(fulfilled),失敗(rejected)贯涎。
- 默認(rèn)狀態(tài)為等待听哭,等待可以變?yōu)槌晒Γ却梢宰優(yōu)槭 ?/li>
- 狀態(tài)一旦更改不可改變塘雳,成功不能變回等待陆盘,失敗不能變回等待,成功不能變成失敗败明,失敗不能變成成功隘马。
- Promise 基礎(chǔ)語法
const promise = new Promise(function (resolve, reject) {
fs.readFile("./x.txt", "utf-8", function(error, data) {
if (error) {
// 將狀態(tài)從等待變?yōu)槭? reject(error)
} else {
// 將狀態(tài)從等待變?yōu)槌晒? resolve(data)
})
});
promise.then(function (data) {
console.log(data)
}).catch(function (error) {
console.log(error)
})
Promise 鏈?zhǔn)秸{(diào)用
Promise.all 并發(fā)異步操作
const fs = require("fs")
Promise.all([
readFile("./x.txt"),
readFile("./y.txt"),
readFile("./z.txt")
]).then(function (data) {
console.log(data)
})
基于異步函數(shù)的異步編程
Promise 雖然解決了回調(diào)地獄的問題,但是代碼看起來仍然不簡(jiǎn)潔妻顶。
使用異步函數(shù)簡(jiǎn)化代碼提高異步編程體驗(yàn)酸员。
##### 1. 異步函數(shù)概述
function readFile(path) {
return new Promise(function (resolve, reject) {
fs.readFile(path, "utf-8", function (error, data) {
if (error) return reject(error)
resolve(data)
})
})
}
async function getFileContent() {
let x = await readFile("./x.txt")
let y = await readFile("./y.txt")
let z = await readFile("./z.txt")
return [x, y, z]
}
getFileContent().then(console.log)
- async 聲明異步函數(shù)的關(guān)鍵字,異步函數(shù)的返回值會(huì)被自動(dòng)填充到 Promise 對(duì)象中讳嘱。
- await 關(guān)鍵字后面只能放置返回 Promise 對(duì)象的 API幔嗦。
- await 關(guān)鍵字可以暫停函數(shù)執(zhí)行,等待 Promise 執(zhí)行完后返回執(zhí)行結(jié)果沥潭。
- await 關(guān)鍵字只能出現(xiàn)在異步函數(shù)中邀泉。
- await 關(guān)鍵字后面只能放置返回 Promise 對(duì)象的 API幔嗦。
##### 2. util.promisify
在 Node.js 平臺(tái)下,所有異步方法使用的都是基于回調(diào)函數(shù)的異步編程。為了使用異步函數(shù)提高異步編程體驗(yàn)汇恤,可以使用 util 模塊下面的 promisify 方法將基于回調(diào)函數(shù)的異步 API 轉(zhuǎn)換成返回Promise 的API庞钢。
const util = require("util")
const readFile = util.promisify(fs.readFile)
async function getFileContent() {
let x = await readFile("./x.txt", "utf-8")
let y = await readFile("./y.txt", "utf-8")
let z = await readFile("./z.txt", "utf-8")
return [x, y, z]
}
getFileContent().then(console.log)
32、事件循環(huán)機(jī)制 Event Loop 機(jī)制概述
- 事件循環(huán)機(jī)制用于管理異步 API 的回調(diào)函數(shù)什么時(shí)候回到主線程中執(zhí)行因谎。
- Node.js 采用的是異步 I/O 模型基括。同步 API 在主線程中執(zhí)行,異步 API 在底層的 C++ 維護(hù)的線程中執(zhí)行财岔,異步 API 的回調(diào)函數(shù)在主線程中執(zhí)行阱穗。在 JavaScript 應(yīng)用運(yùn)行時(shí),眾多異步 API 的回調(diào)函數(shù)什么時(shí)候能回到主線程中調(diào)用呢使鹅?這就是事件循環(huán)機(jī)制做的事情揪阶,管理異步 API 的回調(diào)函數(shù)什么時(shí)候回到主線程中執(zhí)行。
- 因?yàn)?Node.js 是事件驅(qū)動(dòng)的患朱。事件驅(qū)動(dòng)就是當(dāng)什么時(shí)候做什么事情鲁僚,做的事情就定義在回調(diào)函數(shù)中,可以將異步 API 的回調(diào)函數(shù)理解為事件處理函數(shù)裁厅,所以管理異步API回調(diào)函數(shù)什么時(shí)候回到主線程中調(diào)用的機(jī)制叫做事件循環(huán)機(jī)制冰沙。
33、 Event Loop 的六個(gè)階段
事件循環(huán)是一個(gè)循環(huán)體执虹,在循環(huán)體中有六個(gè)階段拓挥,在每個(gè)階段中,都有一個(gè)事件隊(duì)列袋励,不同的事件隊(duì)列存儲(chǔ)了不同類型的異步API 的回調(diào)函數(shù)侥啤。
- Timers:用于存儲(chǔ)定時(shí)器的回調(diào)函數(shù)(setInterval, setTimeout)。
- Pending callbacks:執(zhí)行與操作系統(tǒng)相關(guān)的回調(diào)函數(shù)茬故,比如啟動(dòng)服務(wù)器端應(yīng)用時(shí)監(jiān)聽端口操作的回調(diào)函數(shù)就在這里調(diào)用盖灸。
- Idle, prepare:系統(tǒng)內(nèi)部使用。
- IO Poll:存儲(chǔ) I/O 操作的回調(diào)函數(shù)隊(duì)列磺芭,比如文件讀寫操作的回調(diào)函數(shù)赁炎。如果事件隊(duì)列中有回調(diào)函數(shù),執(zhí)行它們直到清空隊(duì)列钾腺。否則事件循環(huán)將在此階段停留一段時(shí)間以等待新的回調(diào)函數(shù)進(jìn)入徙垫,這個(gè)等待取決于以下兩個(gè)條件:
1. setImmediate 隊(duì)列(check 階段)中存在要執(zhí)行的回調(diào)函數(shù).
2. timers 隊(duì)列中存在要執(zhí)行的回調(diào)函數(shù). 在這種情況下, 事件循環(huán)將移至 check 階段, 然后移至Closing callbacks 階段, 并最終從 timers 階段進(jìn)入下一次循環(huán)。 - Check:存儲(chǔ) setImmediate API 的回調(diào)函數(shù)放棒。
- Closing callbacks:執(zhí)行與關(guān)閉事件相關(guān)的回調(diào)姻报,例如關(guān)閉數(shù)據(jù)庫連接的回調(diào)函數(shù)等。
循環(huán)體會(huì)不斷運(yùn)行以檢測(cè)是否存在沒有調(diào)用的回調(diào)函數(shù)哨查,事件循環(huán)機(jī)制會(huì)按照先進(jìn)先出的方式執(zhí)行他們直到隊(duì)列為空逗抑。
34、宏任務(wù)與微任務(wù)(異步API的類型)
- 宏任務(wù):setInterval, setTimeout, setImmediate, I/O
- 微任務(wù):Promise.then Promise.catch Promise.finally, process.nextTick
- 微任務(wù)與宏任務(wù)的區(qū)別
1. 微任務(wù)的回調(diào)函數(shù)被放置在微任務(wù)隊(duì)列中寒亥,宏任務(wù)的回調(diào)函數(shù)被放置在宏任務(wù)隊(duì)列中邮府。
2. 微任務(wù)優(yōu)先級(jí)高于宏任務(wù)。
當(dāng)微任務(wù)事件隊(duì)列中存在可以執(zhí)行的回調(diào)函數(shù)時(shí)溉奕,事件循環(huán)在執(zhí)行完當(dāng)前階段的回調(diào)函數(shù)后會(huì)暫停進(jìn)入事件循環(huán)的下一個(gè)階段褂傀,事件循環(huán)會(huì)立即進(jìn)入微任務(wù)的事件隊(duì)列中開始執(zhí)行回調(diào)函數(shù),當(dāng)微任務(wù)隊(duì)列中的回調(diào)函數(shù)執(zhí)行完成后加勤,事件循環(huán)再進(jìn)入到下一個(gè)階段開始執(zhí)行回調(diào)函數(shù)仙辟。
nextTick 的優(yōu)先級(jí)高于 microTask,在執(zhí)行任務(wù)時(shí)鳄梅,只有 nextTick 中的所有回調(diào)函數(shù)執(zhí)行完成后才會(huì)開始執(zhí)行 microTask叠国。
不同階段的宏任務(wù)的回調(diào)函數(shù)被放置在了不同的宏任務(wù)隊(duì)列中,宏任務(wù)與宏任務(wù)之間沒有優(yōu)先級(jí)的概念戴尸,他們的執(zhí)行順序是按照事件循環(huán)的階段順序進(jìn)行的粟焊。
35、 Event Loop 代碼解析
- 在 Node 應(yīng)用程序啟動(dòng)后孙蒙,并不會(huì)立即進(jìn)入事件循環(huán)项棠,而是先執(zhí)行輸入代碼,從上到下開始執(zhí)行挎峦,同步API 立即執(zhí)行香追,異步 API 交給 C++ 維護(hù)的線程執(zhí)行,異步 API 的回調(diào)函數(shù)被注冊(cè)到對(duì)應(yīng)的事件隊(duì)列中坦胶。當(dāng)所有輸入代碼執(zhí)行完成后透典,開始進(jìn)入事件循環(huán)。
36顿苇、process.nextTick()
- 此方法的回調(diào)函數(shù)優(yōu)先級(jí)最高掷匠,會(huì)在事件循環(huán)之前被調(diào)用。
- 如果你希望異步任務(wù)盡可能早地執(zhí)行岖圈,那就使用 process.nextTick讹语。
37、setImmediate()
- setImmediate 表示立即執(zhí)行蜂科,它是宏任務(wù)顽决,回調(diào)函數(shù)會(huì)被會(huì)放置在事件循環(huán)的 check 階段。
- 在應(yīng)用中如果有大量的計(jì)算型任務(wù)导匣,它是不適合放在主線程中執(zhí)行的才菠,因?yàn)橛?jì)算任務(wù)會(huì)阻塞主線程,主線程一旦被阻塞贡定,其他任務(wù)就需要等待赋访,所以這種類型的任務(wù)最好交給由 C++ 維護(hù)的線程去執(zhí)行。
- 可以通過 setImmediate 方法將任務(wù)放入事件循環(huán)中的 check 階段,因?yàn)榇a在這個(gè)階段執(zhí)行不會(huì)阻塞主線程蚓耽,也不會(huì)阻塞事件循環(huán)渠牲。
- Node 適合 I/O 密集型任務(wù),不適合 CPU 密集型任務(wù)步悠,因?yàn)橹骶€程一旦阻塞签杈,程序就卡主了。
38鼎兽、web 網(wǎng)站的組成
- 從開發(fā)者的角度來看答姥,web 應(yīng)用主要由三部分組成:用戶界面,業(yè)務(wù)邏輯谚咬,數(shù)據(jù)鹦付。
- 用戶界面 (視圖層):用于將數(shù)據(jù)展示給用戶的地方,采用 HTML择卦,CSS敲长,JavaScript 編寫。
- 業(yè)務(wù)邏輯 (控制層):實(shí)現(xiàn)業(yè)務(wù)需求和控制業(yè)務(wù)流程的地方互捌,可以采用 Java, PHP, Python, JavaScript編寫潘明。
- 數(shù)據(jù) (模型層):應(yīng)用的核心部分, 應(yīng)用業(yè)務(wù)邏輯的實(shí)現(xiàn),用戶界面的展示都是基于數(shù)據(jù)的秕噪, web 應(yīng)用中的數(shù)據(jù)通常是存儲(chǔ)在數(shù)據(jù)庫中的钳降,數(shù)據(jù)庫可以采用 MySql, Mongodb 等。
39腌巾、什么是 web 服務(wù)器
- 服務(wù)器是指能夠向外部(局域網(wǎng)或者萬維網(wǎng))提供服務(wù)的機(jī)器(計(jì)算機(jī))就是服務(wù)器遂填。
- 在硬件層面,web 服務(wù)器就是能夠向外部提供網(wǎng)站訪問服務(wù)的計(jì)算機(jī)澈蝙。
- 在這臺(tái)計(jì)算機(jī)中存儲(chǔ)了網(wǎng)站運(yùn)行所必須的代碼文件和資源文件吓坚。
- 在軟件層面,web 服務(wù)器控制著用戶如何訪問網(wǎng)站中的資源文件灯荧,控制著用戶如何與網(wǎng)站進(jìn)行交互礁击。
- 客戶端:web 應(yīng)用中的客戶端是指用戶界面的載體,實(shí)際上就是瀏覽器逗载。用戶可以通過瀏覽器這個(gè)客戶端訪問網(wǎng)站應(yīng)用的界面哆窿,通過用戶界面與網(wǎng)站應(yīng)用進(jìn)行交互。
- 網(wǎng)站的運(yùn)行:web 應(yīng)用是基于請(qǐng)求和響應(yīng)模型的厉斟。
40挚躯、IP和域名
- IP:Internet Protocol address:互聯(lián)網(wǎng)協(xié)議地址,標(biāo)識(shí)網(wǎng)絡(luò)中設(shè)備的地址擦秽,具有唯一性码荔。例如:45.113.192.101
- 域名 (Domain Name):是由一串用點(diǎn)分隔的字符組成的互聯(lián)網(wǎng)上某一臺(tái)計(jì)算機(jī)或計(jì)算機(jī)組的名稱漩勤,用于在數(shù)據(jù)傳輸時(shí)標(biāo)識(shí)計(jì)算機(jī)的電子方位 (摘自維基百科)。
41缩搅、DNS 服務(wù)器
- Domain Name Server:域名服務(wù)器越败,互聯(lián)網(wǎng)域名解析系統(tǒng),它可以將"人類可識(shí)別"的標(biāo)識(shí)符映射為系統(tǒng)內(nèi)部通常為數(shù)字形式的標(biāo)識(shí)碼誉己。(摘自維基百科)
42眉尸、端口
- 端口:是設(shè)備與外界通訊交流的出口域蜗,此處特指計(jì)算機(jī)中的虛擬端口巨双。0 ~ 65535
- 比如在一座大廈當(dāng)中有很多房間,每間房間都提供著不同的服務(wù)霉祸,我們可以通過房間號(hào)找到提供不同服務(wù)的房間筑累。
- 服務(wù)器就是這座大廈,在服務(wù)器中可以提供很多服務(wù)丝蹭,比如 web 訪問服務(wù)慢宗,郵件的收發(fā)服務(wù),文件的上傳下載服務(wù)奔穿,用戶在找到服務(wù)器以后如何去找具體的服務(wù)呢镜沽?答案就是端口號(hào),端口號(hào)就是大廈中的房間號(hào)贱田,在服務(wù)器中通過端口號(hào)區(qū)分不同的服務(wù)缅茉。
- 也就是說,服務(wù)器中的各種應(yīng)用男摧,要想向外界提供服務(wù)蔬墩,必須要占用一個(gè)端口號(hào)。
- 通常 web 應(yīng)用占用 80 端口耗拓,在瀏覽器中訪問應(yīng)用時(shí) 80 可以省略拇颅,因?yàn)槟J(rèn)就訪問 80。
43乔询、URL
- URL:統(tǒng)一資源定位符樟插,表示我們要訪問的資源在哪以及要訪問的資源是什么。
- protocol :// hostname [:port可選] / path
- http :// www.example.com : 80/ index.html
44竿刁、前臺(tái)和后臺(tái)黄锤,前端和后端
- 前臺(tái)和后臺(tái)都是指用戶界面。前臺(tái)是為客戶準(zhǔn)備的们妥,每個(gè)人都可以訪問的用戶界面猜扮。后臺(tái)是為網(wǎng)站管理員準(zhǔn)備的,只有登錄以后才能訪問的用戶界面监婶,用于管理網(wǎng)站應(yīng)用中的數(shù)據(jù)旅赢。
- 前端是指開發(fā)客戶端應(yīng)用的程序員齿桃。
- 后端是指開發(fā)服務(wù)器端應(yīng)用程序的程序員。
45煮盼、開發(fā)環(huán)境的說明
- 在開發(fā)環(huán)境中短纵,開發(fā)者機(jī)器既充當(dāng)了客戶端的角色又充當(dāng)了服務(wù)器的角色。
- 本機(jī)IP: 127.0.0.1
- 本機(jī)域名: localhost
46僵控、創(chuàng)建 web server
- 創(chuàng)建軟件層面的 web 服務(wù)器香到,用于控制資源要如何被訪問。