寫在前面
總是喜歡自己造輪子, 自己造的輪子又不如已有的輪子好, 然后就半途而廢了. 現(xiàn)在想起來, 還是沒有到自己造輪子的時候啊. 畢竟, 先把東西寫出來才是最重要的.
Node.js的module
Node.js的module非常重要, 因為你為了方便, 會使用很多別人提供的包, 或者叫框架, 所以, 知道Node.js是如何引入的, 就重要了.
把Modules的文檔看一遍就全懂了, 是在沒什么值得寫的. 需要注意的就是module.exports
和exports
, 還有unfinished copy
.
加載的時候會進行一些初始化, 其中module
可以認為是全局對象, 記錄當前塊的信息, 而exports
就是exports = module.exports
, 然后引用你的包. 引用完畢之后, 返回modules.exports
. 而問題就出現(xiàn)在這里. 你使用exports = function func(){}
后, exports
引用的是func
, module.exports
沒受影響. 所以func
沒有被導出. exports
只是作為exports.propertyName = value
的方式使用的.
有一個也值得注意, 就是require.main
指向的是node
命令執(zhí)行腳本是, 這個腳本的module
, 利用require.main
就可以判斷, 本文件是作為腳本直接執(zhí)行的, 還是作為包載入的
if(require.main === module)
// loaded as script
}else{
// loaded as module
}
require
引入一個包的時候大致循序就是如果是相對路徑, 就通過當前文件計算相對路徑.
- 如果指向的是一個核心模塊, 則加載這個模塊并返回.
- 如果指向的是一個文件, 則加載(后綴只能是
.js
,.json
,.node
), 否則當成一個目錄. - 如果是目錄, 則看里面有沒有
package.json
, 有的話, 計算main
字段指向的文件, 跳到步驟2加載, 如果沒有就看該目錄下有沒有index.js
,index.json
,index.node
. 有就加載, 沒有就看該目錄下的node_modules
下有沒有, 有的話就在其內(nèi)找有沒有符合指向的, 按照2, 3的步驟加載, 沒有就去父目錄的node_modules
下找, 重復3直到根目錄. - 最后, 如果還沒找到, 就去
NODE_PATH
指定的目錄(可以是多個)目錄下接著找.
雖然提供了NODE_PATH
, 但是盡量別用.
現(xiàn)在的目錄結構差不多都是這個樣子:
project/
src/ # 源代碼
lib/ # 如果作為一個模塊以供使用, 那么源代碼會放到這里
test/ # 測試
dist/ # 壓縮過的代碼, 用于生產(chǎn)環(huán)境, 前端庫經(jīng)常有這個目錄
package.json # 利用"main"指向入口文件
README.md # 項目說明
npm
npm
作為包管理工具, 使用挺簡單的, 其實看一遍文檔就可以懂了. 文檔也很短.
Node.js
已經(jīng)提供了模塊機制, 這就為依賴管理奠定了基礎. 使用npm
的好處是什么呢? 管理代碼依賴更輕松. 如果把項目分為不同的包, 既有利于一起開發(fā); 在下一個項目中, 也可以輕易重用. 包的開發(fā)者可以自由開發(fā)不同版本, 而使用者也可以通過版本號指定采用哪個版本.
指定版本的時候可以指定一定范圍, 以使用較新版本的包
Patch releases: 1.0 or 1.0.x or ~1.0.4
Minor releases: 1 or 1.x or ^1.0.4
Major releases: * or x
Node.js自帶npm, 但是由于npm更新比Node.js更新更頻繁, 所以有的時候需要手動更新npm
sudo npm install -g npm@latest
有時候npm很慢, 可以換別的源. 使用nrm可以輕松更換源. 一般來說, 國內(nèi)淘寶比較快.
sudo npm install -g nrm # 安裝nrm
nrm test # 顯示各個院的時延
nrm set <repo> # 設置當前源為repo
Node.js會發(fā)布新版本, 如果是Linux下, 你有福了, 可以使用工具, 在命令行上更換不同版本的Node.js(包括Io.js)
sudo npm install -g n # 安裝n
n lts # 將Node.js切換到最新的長期支持版本
n stable # 將Node.js切換到最新的穩(wěn)定版本
n latest # 將Node.js切換到最新版本
對于npm
來說, 一個包就是一個文件夾, 里面包含package.json
和代碼. package.json
用來描述這個包的信息, 其中, 有幾個重要的信息:
-
name
, 名字 -
version
, 版本號 -
main
, 入口文件 -
scripts
, 腳本 -
keywords
, 關鍵字 -
author
, 作者信息author-name <email@host.com> (personal.me)
-
license
, 包使用的協(xié)議 -
repository
, 維護信息 -
bugs
, 遞交bugs
的鏈接 -
homepage
, 項目主頁 -
dependencies
, 程序依賴的包, 是一個JavaScript
對象, 屬性名是包名, 屬性值是依賴的版本號, 這里可以通過一定的語義來指定一定范圍內(nèi)的版本, 方便以后對被依賴的包進行升級. -
devDependencies
, 開發(fā)過程中依賴的包, 同dependencies
安裝包很簡單. 指定了-g
就是全局安裝, 包被放在$(npm config get prefix)/node_modules/
目錄下, 可以在命令行中使用. 前面的nrm
, n
都是這種. 沒有-g
參數(shù)的就是本地安裝, 代碼存放在./node_modules/
目錄下, 并可以用require
引入.
npm install -g <package-name>
如果沒有指定<package-name>
的話, 則自動安裝package.json
中dependencies
中指定的包.
如果指定了--save
或者-S
, 則將這個包的信息自動同步到package.json
的dependencies
中, 而如果指定了--save-dev
或-D
, 則將這個包的信息自動同步到package.json
的devDependencies
中. 這倆參數(shù)在卸載等命令中都可以使用.
npm ls
列出所有已經(jīng)安裝的包, 如果./node_modules/
目錄有的包不在package.json
中, 則顯示是多余的, 可以用npm prune
來刪除多余的包, 而在package.json
中指定的在./node_modules/
中沒有, 則使用npm install
進行安裝, 這可以安裝很多確實的包.
npm outdated
會根據(jù)package.json
執(zhí)行的版本范圍來檢查當前包是否過期, 如果過期了, 就會顯示過期信息. 可以通過npm update
統(tǒng)一升級, 如果只想更新某一個, 則指定報名即可.
卸載包可以使用npm uninstall [-S] [-D] [-g] <package-name>
來刪除包.
如果在./node_modules/
目錄下存在一些包, 在package.json
中沒有依賴, 則可以用npm prune
刪除這些多余的包.
創(chuàng)建包, 首先要創(chuàng)建package.json
. 可以使用npm init
來進入提示, 依次輸入相應的信息, 最后會為你生成一個package.json
文件. 如果加上-y
參數(shù), 則會直接生成package.json
. 這些默認的值可以在npm config set init.<key> <value>
設置, 而如果./node_modules/
下有包, 則會自動添加到依賴里面.
發(fā)布包需要一個賬號, 利用npm adduser
創(chuàng)建賬戶, 如果有賬戶了, 則利用npm login
進行登錄. 到工程所在目錄運行npm publish
就發(fā)布成功了. package.json
必須有name
和version
.
發(fā)布新版本的包的時候, 需要修改package.json
的version
. 可以使用npm version [major|minor|patch]
來更新版本號. 如果是git項目會添加tag
. 再使用npm publish
發(fā)布即可.
最后
npm
挺簡單的, 但是寫了這么多, 寫筆記的時間比看文檔的事件都長. 下次只記錄那些值得記錄的.