Node 語法
一、什麼是 node
node 不是後臺語言,它是一個工具或者環境,解析 js 的工具或者環境,而說它是後臺語言,主要的原因是:我們一般會把 node 安裝在服務器上,在服務器端寫一些 js 代碼,通過 node 執行這些代碼,實現服務器要做的一些功能。所以我們可以說 js 是全棧語言,全棧是什麼?
-
應用 node 環境做的一些事情,基於 v8 引擎渲染和解析 js ,類似於 webview / 谷歌瀏覽器等
-
怎麼執行?
基於命令: $ node xxx.js 把 js 代碼在 node 環境中執行
基於 repel 模式:(Read-Evaluate-Print-Loop, 輸入-求值-輸出-循環)$ node
我們後期學習的 webpack (自動化項目部署)就是基於 node 環境運行的
npm (Node Package Manager)是安裝 node 自帶的模塊管理工具,基於它可以安裝和卸載對應的模塊,類似的模塊管理工具:borwer、yarn
- nmp 安裝模塊是從 npmjs.com 下載
- borwer 安裝模塊是從 github.com 下載
項目架構1
項目架構2
項目架構3
二、 i / o
I:input 輸入,O:output 輸出,I/O 一般指對文件的讀寫操作
- JS 在客戶端瀏覽器中運行,能否對客戶端本地的文件進行讀寫操作?
答案:不能,因爲要保證客戶端的信息安全
input:type = ‘file’ 文件上傳這種除外,但是這種也需要用戶手動選擇後纔可以
- JS 在服務器端運行(基於 NODE 運行),能否對服務器端的文件進行操作?
答案:可以的
NODE 賦予了 JS 進行 I/O 操作的能力(內置模塊:fs)
三、window & global
-
在客戶端瀏覽器中運行 JS,JS 全局對象是:window(提供了很多內置的屬性和方法)
-
在 NODE 中運行 JS,全局對象是:global
- process :node 中進程管理的屬性
- process.nextTick()
- process.env NODE 全局環境變量
- Buffer
- setImmediate 立即執行(類似於setTimeout(func, 0))
- 在REPL命令中輸出的 this 是 global,但是在 xxx.js 中輸出的 this 是當前模塊本身
四、NPM
- 模塊管理(安裝和卸載)
安裝在全局環境下和安裝在當前項目中
- 全裝在全局:$ npm install xxx --global ($ npm i -g xxx)
- 安裝在本地項目中:$ npm i xxx
把模塊設置爲開發依賴(開發中):$ npm i xxx --save-dev
把模塊設置爲生產依賴(部署到服務器):$ npm i xxx --save
- 安裝在全局和本地的區別
安裝在全局後對任何項目都有作用(也有可能導致版本衝突),但是隻能基於命令的方式管理,不能基於CommonJS 中的 require 導入使用(通俗說:就是不能導入到文件中基於代碼來處理)
- $ npm root -g 查看全局安裝到的目錄
- 之所以可以使用命令操作,是因爲在全局目錄下生成了一個 xxx.cmd 的文件
安裝在本地默認不能基於命令管理,但是可以導入到文件中基於代碼操作,只對當前項目有用
在本地安裝模塊之前,最好先:$ npm init -y,生成 package.json 模塊配置文件,把安裝的模塊生成配置清單,存放在 package.json 中,後期別人需要部署項目的時候,只需要執行 $ npm i 就可以把所有的依賴項重新安裝一遍 “跑環境”
- $ npm i 是把開發和生產依賴都安裝一遍
- $ npm i --production 只安裝生產依賴的模塊
在 package.json 中,可以基於 scripts 選項配置本地可執行的腳本命令 $npm run xxx
"scripts": {
// AAA 是命令,值是要做的事情
"AAA": "node xxx.js"
}
在配置可執行腳本命令的時候,基於process的環境變量區分開發還是生產環境
"scripts": {
// set NODE_EVN=dev 設置全局環境變量(MAC下用 export NODE_EVN=dev)
"serve": "set NODE_EVN=dev&&node test1.js",
"build": "set NODE_EVN=pro&&node test1.js"
}
五、CommonJS模塊管理機制
AMD:require.js
CMD:sea.js
CommonJS:node.js
ES6 Module
這些模塊化思想,規定了在JS中我們的模塊該如何的創建、如何的導入以及如何導出
1. 內置模塊
NODE中自帶的
- http/https 創建和管理服務的模塊
- fs 給予JS進行I/O操作的
- url 解析URL地址的
- path 管理路徑的
- …
2. 第三方模塊
基於npm安裝,別人寫好供我們用的
- mime
- qs
- express
- express-session
- body-parser
- …
3. 自定義模塊:自己寫的模塊
六、NODE中的模塊管理
-
在 NODE 環境下,我們每創建一個 JS,都相當於創建了一個新的模塊;模塊中的方法也都是模塊的私有方法,不同模塊之間的同名方法不會有任何的衝突
-
module.exports 就是 NODE 天生自帶的用來導出模塊中方法的方式
module.exports = {
// 這些屬性方法就是需要暴露給外面調取使用的
xxx:xxx
};
- require 是 NODE 天生提供的用來導入模塊的方法
//語法:
let [模塊名] = require([模塊的地址]);
// 例如:
// 1. 可以省略 .js 後綴名
// 2. 如果是調取自己定義的模塊,則需要加 /(根目錄) ./(當前目錄) ../(上級目錄) 這三個中的某一個
// 3.不加上述地址,則先找第三方模塊(安裝在自己本地的),如果沒有安裝,則找NODE中的內置模塊,如果再沒
// 有,則報錯
let A = require('./A');
let qs = require('qs');
- require 導入模塊是同步的(沒導入完成,後面的事情是不處理的);每一次導入模塊都是把導入的模塊中的 JS代碼從上到下執行一遍(只執行一遍)
一個小應用
需求:創建 A / B / C 三個模塊
- A 中有一個 sum 方法實現任意數求和
- B 中有一個辦法 avg 是求平均數:去掉最大和最小值,剩餘值求和(調取 A 中的 sum 方法,實現求和)
- C 中調取 B 中的 avg ,傳遞:98 95 85 67 25,實現求一堆數中的平均數
A:
let sum = (...arg) => eval(arg.join('+'));
module.exports = {
sum
};
B:
let A = require('./A');
let avg = (...arg) => {
arg = arg.sort((a, b) => a - b).slice(1, arg.length - 1);
return (A.sum(...arg) / arg.length).toFixed(2);
};
module.exports = {
avg
};
C:
let {
avg
} = require('./B');
console.log(avg(98, 95, 85, 67, 25));