文章目錄
一、Node開發需要模塊化
概念
ES6之前
ECMAScript存在以下幾個問題
- 沒有模塊系統
- 官方標準庫少/標準接口少
- 缺乏包管理系統
模塊化
- 如果程序設計的規模達到了一定程度,則必須對其進行模塊化
前端沒多大必要, 所以不太需要
服務器端開發, 沒有模塊化開發思想就玩不轉了 - 模塊化可以有多種形式,但都提供了能夠將代碼分割爲多個源文件的機制
Common.js
CommonJS規範
- CommonJS規範的提出,主要是爲了彌補JavaScript沒有模塊化標準的缺陷
- CommonJS規範爲JS希望JS能夠在任何地方運行:這是一個美好的願景
- CommonJS對模塊的定義
模塊引用:require(“路徑”);
模塊定義
模塊標識
總結
- 從文件角度看, 每個JS文件就是一個模塊
- 從結構看, 多個JS文件之間可以相互require,共同實現了一個功能,這整體上也是一個模塊
- 在Node.js中,一個模塊中定義的變量、 函數等, 都只能在這個文件內部有效
- 當需要從此JS文件外部引用這些變量,、函數時,必須使用exports進行暴露,使用者通過require引用
實踐1
-
在Node中,一個js文件就是一個模塊
-
在Node中,通過require()函數來引入外部的模塊
引入外部模塊要加上 . 或者 … -
在Node中,每一個js文件中的js代碼都是獨立運行在一個小閉包中, 而不是全局作用域,所以一個模塊的中的變量和函數在其他模塊中無法訪問
目的: 全局變量私有化, 避免全局污染 -
暴露模塊中的變量和函數
export
只需要將需要暴露給外部的變量或方法設置爲exports的屬性即可02.js
let site = 'www.itlike.com'; let log = ()=>{ console.log('這是一個神奇的網站:', site); }; exports.site = site; exports.log = log;
03.js
// 1. 引入其它模塊 let fn = require('./02.js'); // console.log(fn); console.log(fn.site); fn.log();
實踐2
模塊標識
- 當我們使用require()引入外部模塊時,使用的就是模塊標識,我們可以通過模塊標識來找到指定的模塊
比如: let myFunc = require("./js/myFunc"); - 分類
① 內建模塊:底層由C++編寫
② 文件模塊:由用戶自己創建的模塊
標識:文件的路徑(絕對路徑,相對路徑)
③ 核心模塊:由node引擎提供的模塊、由node_modules提供的模塊
標識:模塊的名字、http、fs、global…
…
思考: export和require怎麼來的?
- 錯誤答案: 全局變量
1)window不是Node中的全局對象
2)Node中有一個全局對象global, 作用和window類似 - 正確答案: 函數參數
1)函數的標識: arguments
獲取函數的所有實參
2)獲取函數自身 arguments.callee
返回函數本身
node文件組成剖析
- 當node在執行模塊中的代碼時,它會首先在代碼的最頂部,添加如下代碼 function (exports, require, module, __filename, __dirname) {
- 在代碼的最底部,添加 }
- 所以模塊中的代碼都是包裝在一個函數中執行的,並且在函數執行的同時傳遞進了5個實參
① exports: 該對象用來將函數內部的局部變量或局部函數暴露到外部
② require: 用來引入外部的模塊
③ module: 代表的是當前模塊本身, exports就是module的屬性; 我們既可以使用 exports 導出,也可以使用module.exports導出
④ __filename: 當前模塊的完整路徑
⑤ __dirname: 當前模塊所在文件夾的完整路徑
Node中的Common.js
-
在node.js 裏,模塊劃分所有的功能,每個JS都是一個模塊
-
實現require方法,NPM實現了模塊的自動加載和安裝依賴
-
內部形式
(function(exports,require,module,__filename,__dirname){ exports = module.exports={} exports.brands = 'itlike'; exports = {brands :'itlike'}; return module.exports; })
exports 和 module.exports的區別
兩者區別
- 在每一個模塊中,最終返回的是module.exports
所以module改變方式是不受影響的,但exports改變就無法正確返回。(function(exports,require,module,__filename,__dirname){ exports = module.exports={}; return module.exports; })
- exports只能使用.語法來向外暴露內部變量
exports.xxx = xxx; - module.exports既可以通過.語法,也可以直接賦值一個對象
module.exports.xxx = yyy;
module.exports = {xxx: yyy};
值類型和引用類型
二、module&NPM
模塊分類
原生模塊
http path fs util events 編譯成二進制,加載速度最快,原生模塊是通過名稱來加載
文件模塊
- 在硬盤的某個位置,加載速度非常慢,文件模塊通過名稱或路徑來加載
- 文件模塊的後綴有三種
① 後綴名爲.js的JavaScript腳本文件,需要先讀入內存再運行
② 後綴名爲.json的JSON文件,需要藉助fs模塊讀入內存,轉化成JSON對象
③ 後綴名爲.node的經過編譯後的二進制C/C++擴展模塊文件,可以直接使用 - 注意
① 一般自己寫的通過路徑來加載
② 其他人寫的通過名稱去當前目錄或全局的node_modules下面去找
第三方模塊
- 如果require函數只指定名稱,則視爲從node_modules下面加載文件,這樣的話,我們可以移動模塊而不需要修改引用的模塊路徑
- 第三方模塊的查詢路徑包括module.paths和全局目錄
- 全局目錄
① window如果在環境變量中設置了NODE_PATH變量,並將變量設置爲一個有效的磁盤目錄,require在本地找不到此模塊時,會向上在此目錄下繼續找這個模塊
② UNIX操作系統中會從 $HOME/.node_modules $HOME/.node_libraries目錄下尋找 - 模塊加載策略
包
- 在Node.js中,可以通過包來對一組具有相互依賴關係的模塊進行統一管理,通過包可以把某個獨立功能封裝起來
- 每個項目的根目錄下面,一般都有一個package.json文件,定義了這個項目所需要的各種模塊,以及項目的配置信息(比如名稱、版本、許可證等元數據)
- 使用
npm init
命令初始化包 npm install
命令根據這個配置文件,自動下載所需的模塊,也就是配置項目所需的運行和開發環境- 圖示
NPM
概念
- 安裝完node之後只能使用Node語言特性及核心函數,我們還需要一個系統來下載、安裝和管理第三方模塊。
- 在 Node看這個系統被稱爲Node包管理器(Node Package Manager,NPM)
npm提供的功能
- 公共註冊服務,用戶可以把自己寫的包上傳到服務器上
- 命令行下載工具,用戶可以通過npm命令把別人寫的包下載到自己電腦上,還可以管理自己模塊依賴的其它模塊
- 搜索第三方包的地址:https://www.npmjs.com/search
npm命令
- 安裝包
打開命令行或終端,進入要安裝包的目錄,然後執行以下命令安裝依賴的模塊
npm install <package-name>
npm i jquery
此命令會從服務器上下載此模塊到當前目錄下的node_modules目錄下,如果node_modules目錄不存在則會創建一個, 也可以安裝特定的版本
npm install <package name>@<version spec>
npm i [email protected]
npm i [email protected]
- 卸載包
npm uninstall <package name>
- 更新包
npm update <package name>
包的安裝模式
- 本地安裝
① 默認情況下安裝命令會把對應的包安裝到當前目錄下,這叫本地安裝
② 如果包裏有可執行的文件,NPM會把可執行文件安裝到./node_modules/.bin目錄下
③ 本地安裝的模塊只能在當前目錄和當前目錄的子目錄裏面使用 - 全局安裝
① 希望安裝的包能夠在計算機機的所有目錄下面都能使用,就需要全局安裝
npm install <package-name> -g
② 在全局安裝的模式下,npm會把包安裝到全局目錄,通過此命令可以查看當前全局目錄的位置
③ 如果要修改全局安裝目錄,可以使用
npm config set prefix “E:\node.js\node_global”
- 註冊、登錄和發佈模塊
註冊npm賬號 https://www.npmjs.com/
登錄,npm login
發佈,npm publish
yarn
概念
- yarn 是一個依賴管理工具
- 它能夠管理你的代碼,並與全世界的開發者分享代碼
- 代碼是通過包(有時也被稱爲模塊)進行共享的
- 在每一個包中包含了所有需要共享的代碼,另外還定義了一個package.json文件,用來描述這個包
安裝yarn
npm yarn --save -g
初始化一個新的項目
yarn init
添加一個依賴包
yarn add [package]
yarn add [package]@[version]
yarn add [package]@[tag]
更新一個依賴包
yarn upgrade [package]
yarn upgrade [package]@[version]
yarn upgrade [package]@[tag]
刪除一個依賴包
yarn remove [package]
安裝所有的依賴包
yarn
yarn install