node.js基礎(chǔ)

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ù)中邀泉。
##### 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ù)鹦付。
    1. 用戶界面 (視圖層):用于將數(shù)據(jù)展示給用戶的地方,采用 HTML择卦,CSS敲长,JavaScript 編寫。
    2. 業(yè)務(wù)邏輯 (控制層):實(shí)現(xiàn)業(yè)務(wù)需求和控制業(yè)務(wù)流程的地方互捌,可以采用 Java, PHP, Python, JavaScript編寫潘明。
    3. 數(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ù)器香到,用于控制資源要如何被訪問。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末报破,一起剝皮案震驚了整個(gè)濱河市悠就,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌充易,老刑警劉巖梗脾,帶你破解...
    沈念sama閱讀 212,294評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異盹靴,居然都是意外死亡炸茧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門稿静,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梭冠,“玉大人,你說我怎么就攤上這事改备】啬” “怎么了?”我有些...
    開封第一講書人閱讀 157,790評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵绍妨,是天一觀的道長(zhǎng)润脸。 經(jīng)常有香客問我,道長(zhǎng)他去,這世上最難降的妖魔是什么毙驯? 我笑而不...
    開封第一講書人閱讀 56,595評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮灾测,結(jié)果婚禮上爆价,老公的妹妹穿的比我還像新娘。我一直安慰自己媳搪,他們只是感情好铭段,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秦爆,像睡著了一般序愚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上等限,一...
    開封第一講書人閱讀 49,906評(píng)論 1 290
  • 那天爸吮,我揣著相機(jī)與錄音芬膝,去河邊找鬼。 笑死形娇,一個(gè)胖子當(dāng)著我的面吹牛锰霜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播桐早,決...
    沈念sama閱讀 39,053評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼癣缅,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了哄酝?” 一聲冷哼從身側(cè)響起友存,我...
    開封第一講書人閱讀 37,797評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炫七,沒想到半個(gè)月后爬立,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钾唬,經(jīng)...
    沈念sama閱讀 44,250評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡万哪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抡秆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奕巍。...
    茶點(diǎn)故事閱讀 38,711評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖儒士,靈堂內(nèi)的尸體忽然破棺而出的止,到底是詐尸還是另有隱情,我是刑警寧澤着撩,帶...
    沈念sama閱讀 34,388評(píng)論 4 332
  • 正文 年R本政府宣布诅福,位于F島的核電站,受9級(jí)特大地震影響拖叙,放射性物質(zhì)發(fā)生泄漏氓润。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評(píng)論 3 316
  • 文/蒙蒙 一薯鳍、第九天 我趴在偏房一處隱蔽的房頂上張望咖气。 院中可真熱鬧,春花似錦挖滤、人聲如沸崩溪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伶唯。三九已至,卻和暖如春惧盹,著一層夾襖步出監(jiān)牢的瞬間乳幸,已是汗流浹背奋救。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留反惕,地道東北人尝艘。 一個(gè)月前我還...
    沈念sama閱讀 46,461評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像姿染,于是被迫代替她去往敵國和親背亥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • 一悬赏、Node.js 簡(jiǎn)介 Node.js 是一個(gè)基于 Chrome V8 引擎 的 JavaScript 運(yùn)行時(shí)...
    王秀龍閱讀 253評(píng)論 0 0
  • 一 .Node.js 基礎(chǔ) 目錄 Node開發(fā)概述Node運(yùn)行環(huán)境搭建Node.js快速入門 1. Node開發(fā)概...
    風(fēng)衫碼農(nóng)閱讀 804評(píng)論 0 2
  • 前端工程化簡(jiǎn)介 工程就是一個(gè)項(xiàng)目(比如一個(gè)網(wǎng)站或者app) 一個(gè)工程的生命周期 工程化就是項(xiàng)目完成過程中闽颇,用到的各...
    amanohina閱讀 357評(píng)論 0 3
  • 什么是前端工程化盾戴?前端工程化又有什么用呢?前端工程化就是在構(gòu)建一個(gè)前端項(xiàng)目的時(shí)候兵多,通過一些技術(shù)跟工具尖啡,來提升前端開...
    琳琳醬吖閱讀 588評(píng)論 0 0
  • 1.課程介紹與開發(fā)環(huán)境搭建 主要包括nodejs 基礎(chǔ)知識(shí)web 服務(wù)器異步 同步 阻塞 非阻塞 課程基礎(chǔ)java...
    shadow123閱讀 654評(píng)論 0 0