1. Node.js 介紹
npm的兩層含義
- npm 是一個(gè)網(wǎng)站,這個(gè)網(wǎng)站上托管了幾十萬個(gè)使用 JavaScript 開發(fā)的功能模塊庫
- npm 是一個(gè)基于Node開發(fā)的一個(gè)終端命令行包管理工具
- 可以使用這個(gè)工具去 npm 網(wǎng)站上下載對應(yīng)的庫
npm 安裝
只要安裝了 node 就有了 npm。
通過 npm -v 測試是否有 npm 工具。
使用 npm 安裝包
- 找到能解決自己問題的包,看文檔使用說明
- 通過
npm install 包名下載到當(dāng)前項(xiàng)目中的根目錄 - 在代碼中通過
require('第三方包名')使用你下載的包
通過 npm install 包名 安裝的包會(huì)自動(dòng)下載到當(dāng)前目錄下的 node_modules 目錄,
如果該目錄不存在,則直接創(chuàng)建,如果已存在,則直接將文件下載進(jìn)去。
使用 Npm 安裝全局命令行工具
在 npm 社區(qū)中,除了有可以在項(xiàng)目中使用的第三方包之外,還有一些特殊的包:
這些特殊的包被稱之為命令行工具,不是用于項(xiàng)目的,而是可以安裝到計(jì)算機(jī)中,
然后通過命令行中的命令的形式來使用,這種工具有很多,例如:http-server、gulp、
browser-sync、nodemon 等等等等很多。
安裝方式:
npm install --global 第三方命令行工具名字
卸載:
npm uninstall --global 第三方命令行工具名稱
查看全局命令行安裝目錄:
npm root --global
1.1 網(wǎng)站開發(fā)模型(BS)
- Server
- 為客戶端提交接口:數(shù)據(jù)
- Java、.Net、Ruby、Python、PHP、Go、Swift、Lua
- 學(xué) Node 本質(zhì)不是在學(xué) Node,在學(xué) 服務(wù)器(Web后臺)編程
- 請求
- 處理
- 響應(yīng)
- 大前端時(shí)代:JavaScript 語言也可以運(yùn)行在服務(wù)器端
- 使用 JavaScript 這門語言也可以進(jìn)行服務(wù)器編程
- JavaScript 通過 Node.js 運(yùn)行在服務(wù)器端
- Browser
- 客戶端:把一堆用戶看不懂的數(shù)據(jù)變成友好的形式給用戶體驗(yàn)
1.2 什么是 Node.js?
簡單的說 Node.js 就是運(yùn)行在服務(wù)端的 JavaScript
Node開發(fā)就是利用 Ecmascript + 第三方開源庫 + Node平臺環(huán)境API進(jìn)行編程
-
什么是 JavaScript
- JavaScript 一個(gè)運(yùn)行在瀏覽器端的腳本原因
- 運(yùn)行時(shí):瀏覽器
- Ecmascript:JavaScript 基本語法:var、if-else、for、Array、Object、String、function
- BOM
- Window
- DOM
- 渲染引擎
- JavaScript 解析執(zhí)行引擎
- 在所有瀏覽器中,Google Chrome 的 V8 引擎是最快的 JS 腳本代碼解析執(zhí)行引擎
- 通過 V8 引擎解析和執(zhí)行 JavaScript 代碼
Node 官網(wǎng):https://nodejs.org/en/
-
Node.js? is a JavaScript runtime built on Chrome's V8 JavaScript engine.
- Node.js 是一個(gè)構(gòu)建與 Chrome V8 引擎之上的一個(gè) JavaScript 運(yùn)行時(shí)(執(zhí)行環(huán)境)
- Node 使用 JavaScript 進(jìn)行編程
- Node 采用了 Chrome 的 V8 引擎解析和執(zhí)行 JavaScript 腳本代碼
- Node 不是一種語言,Node 可以用來解析和執(zhí)行 JavaScript 代碼
- 在 Node 沒有 DOM、BOM 了,也不用去關(guān)心樣式、結(jié)構(gòu)問題了
- Node 在基本的 JavaScript 語言之上,或者在 Node 平臺給 Ecmascript 提供了大量的底層編程接口
- 例如文件IO
- 例如網(wǎng)絡(luò)IO
- 處理數(shù)據(jù)
- 操作數(shù)據(jù)庫
- 構(gòu)建網(wǎng)絡(luò)服務(wù)
- 。。。
-
Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
- event-driven:事件驅(qū)動(dòng)
- 在 Node 中,也采用了類似于瀏覽器端的編程思想,事件模型編程思想
- non-blocking I/O model:非阻塞IO模型
- Node 中大量的通過類似于瀏覽器中 ajax 的方式進(jìn)行編程
- 絕大多數(shù)代碼都是異步編程模型
- lightweight & efficient:輕量和高效
- event-driven:事件驅(qū)動(dòng)
Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
1.3 使用 Node 可以做什么?
- 開發(fā)網(wǎng)站服務(wù)器
- 游戲服務(wù)器
- 開發(fā)命令行工具
- 軟件分為兩種:
- GUI:看得見,鼠標(biāo)點(diǎn)點(diǎn)點(diǎn)
- CLI:命令窗口,各種命令,選項(xiàng)參數(shù)等
2 核心模塊(Node 提供)
以下是常用的核心模塊及作用:
| 核心模塊名 | 作用 |
|---|---|
| fs | 文件操作 |
| http | 網(wǎng)絡(luò)操作 |
| net | 更底層的網(wǎng)絡(luò)操作 |
| os | 操作系統(tǒng)相關(guān) |
| path | 文件路徑操作 |
| querystring | 查詢字符串處理 |
| url | url操作處理 |
2 Node 中的模塊化
模塊通信交互規(guī)則
- 一個(gè) JavaScript 文件就是一個(gè)模塊
- 模塊天生就是一個(gè)私有的作用域,默認(rèn)模塊內(nèi)定義的變量等成員只能被模塊內(nèi)部訪問
- 每一個(gè)模塊中都有一個(gè)
module.exports編程接口對象,默認(rèn)是一個(gè)空對象- 可以通過給
module.exports編程接口對象添加成員向外暴露內(nèi)部成員 - 例如:
var foo = 'bar' module.exports.foo = foo - 上面示例標(biāo)識當(dāng)前模塊向外部暴露了一個(gè)接口對象,內(nèi)部有一個(gè) foo 成員,值是 bar
- 可以通過給
-
require方法可以用來加載模塊,該方法是同步加載執(zhí)行的,主要做兩件事兒- 執(zhí)行被加載模塊中所有的代碼
- 拿到被加載模塊中的
module.exports接口對象
- 拿到被加載模塊中的
用戶自定義模塊
核心模塊
核心模塊就是 Node 提供的模塊,例如 fs、http、path。。。,
這些模塊其實(shí)也是文件模塊,核心模塊一般都是通過一個(gè)固定的標(biāo)識名稱進(jìn)行加載的,
也就是說不能寫錯(cuò),固定的。用什么就加載什么,無論是程序執(zhí)行效率還是可維護(hù)性都非常好。
第三方模塊
也就是npm社區(qū)提供的第三方包,用的時(shí)候,先下載,然后也是通過 require 進(jìn)行加載,
加載第三方模塊的時(shí)候,就是通過 require('第三方模塊標(biāo)識名'),所以第三方模塊不可能有和
核心模塊重名的名稱。
第三方加載模塊有自己的一套加載規(guī)則,node 會(huì)按照對應(yīng)的加載機(jī)制去加載。
具體明天上午會(huì)給大家詳細(xì)解析。
- __dirname
- 用于獲取當(dāng)前文件所屬目錄的絕對路徑
- 使用場景:常用語將相對路徑轉(zhuǎn)為絕對路徑,防止執(zhí)行node命令所處的目錄影響路徑的問題
- __filename
- 作用:獲取當(dāng)前文件的絕對路徑
- process
- process 是Node中一個(gè)進(jìn)程對象,可以用來訪問當(dāng)前運(yùn)行進(jìn)程的一些信息
- global
- 類似于瀏覽器中的 window,是一個(gè)全局對象
- 唯一的區(qū)別在于瀏覽器中的 window 是全局對象,默認(rèn)在全局聲明的變量成員都屬于 window
- Node 中是模塊作用域
- 在一個(gè)模塊系統(tǒng)中,所有的模塊都共享一個(gè) global
- 也就是說可以通過給 global 顯示的掛載成員在多個(gè)模塊之間全局共享
- 雖然可以這樣做,了解即可,盡量不要使用
- 模塊成員
- module
- module 是一個(gè)模塊對象,里面包含了當(dāng)前模塊的一些信息
- 例如 exports 就是當(dāng)前模塊對外的導(dǎo)出接口對象
- exports
- 在每一個(gè)模塊中,同時(shí)還提供了一個(gè)接口成員:
exports -
exports是module.exports接口對象的一個(gè)引用 - 也就是可以把
module.exports.foo=xxx的形式簡寫為exports.foo=xxx - 注意:注重向外的暴露的接口對象是:
module.exports
- 在每一個(gè)模塊中,同時(shí)還提供了一個(gè)接口成員:
- require()
- 執(zhí)行被加載模塊中的代碼
- 拿到被加載模塊中的
module.exports接口對象
3.啟動(dòng)node項(xiàng)目的準(zhǔn)備工作
Babel Register
第一:在項(xiàng)目根目錄下創(chuàng)建一個(gè) .babelrc 文件,寫入以下內(nèi)容:
{
"presets": [
]
}
第二:安裝對應(yīng)的轉(zhuǎn)碼規(guī)則:
# ES2015轉(zhuǎn)碼規(guī)則
$ npm install --save-dev babel-preset-es2015
# react轉(zhuǎn)碼規(guī)則
$ npm install --save-dev babel-preset-react
# ES7不同階段語法提案的轉(zhuǎn)碼規(guī)則(共有4個(gè)階段),選裝一個(gè)
$ npm install --save-dev babel-preset-stage-0
$ npm install --save-dev babel-preset-stage-1
$ npm install --save-dev babel-preset-stage-2
$ npm install --save-dev babel-preset-stage-3
第三:將 .babelrc 文件中修改為以下內(nèi)容:
{
"presets": [
"es2015"
]
}
第四步(從第四步開始,前三部必不可少):
- babel-cli:命令行轉(zhuǎn)碼
- babel-node:babel-cli工具自帶一個(gè)babel-node命令,提供一個(gè)支持ES6的REPL環(huán)境
- babel-register:實(shí)時(shí)轉(zhuǎn)碼,所以只適合在開發(fā)環(huán)境使用
- babel-core:如果某些代碼需要調(diào)用Babel的API進(jìn)行轉(zhuǎn)碼,就要使用babel-core模塊
babel-cli:
一種使用方式就是全局安裝:npm install -g babel-cli(可以通過 npm root -g 查看全局包安裝目錄),
只要全局安裝了 babel-cli,則會(huì)在命令行中多出一個(gè)命令:babel。
這里如果使用全局安裝的 babel-cli 進(jìn)行轉(zhuǎn)碼是沒有問題的,但是問題是如果一旦項(xiàng)目給了別人,
別人不知道你使用了這個(gè)轉(zhuǎn)碼工具,所以解決方式就是將 babel-cli 安裝到本地項(xiàng)目中:
npm install --save-dev babel-cli
這種第三方命令行工具如果安裝到本地項(xiàng)目,會(huì)在 node_modules 中生成一個(gè)目錄:.bin,
然后第三方命令行工具會(huì)將對應(yīng)的可執(zhí)行文件放到該目錄中。
這樣的話,就可以直接在本地項(xiàng)目中使用該第三方命令行工具了。
對于如何使用,則可以通過配置 package.json 文件中的 scripts 字段來配置使用:
{
"name": "babel-demo",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "babel demo1.js"
},
"devDependencies": {
"babel-cli": "^6.22.2",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.22.0"
}
}
babel-register(適合開發(fā)階段,實(shí)時(shí)編碼轉(zhuǎn)換):
第一:安裝 babel-register
npm install --save-dev babel-register
第二:添加一個(gè)傀儡文件(main.js):
require('babel-register')
require('你的核心功能代碼入口文件模塊')
第三:使用 node 執(zhí)行 main.js,而不是你的入口文件.
--save 和 --save-dev
通過 --save 參數(shù)安裝的包,是將依賴項(xiàng)保存到 package.json 文件中的 dependencies 選項(xiàng)中。
通過 --save-dev 參數(shù)安裝的包,是將依賴項(xiàng)保存到 package.json 文件中的 devDependencies 選項(xiàng)中。
無論是 --save 或者 --save-dev 安裝的包,通過執(zhí)行 npm install 都會(huì)將對應(yīng)的依賴包安裝進(jìn)來。
但是,在開發(fā)階段會(huì)有一些僅僅用來輔助開發(fā)的一些第三方包或是工具,然后最終上線運(yùn)行(到了生產(chǎn)環(huán)境),
這些開發(fā)依賴項(xiàng)就不再需要了,就可以通過 npm install --production 命令僅僅安裝 dependencies 中的
依賴項(xiàng)。