寫在前面
總是喜歡自己造輪子, 自己造的輪子又不如已有的輪子好, 然后就半途而廢了. 現(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)在的目錄結(jié)構(gòu)差不多都是這個樣子:
project/
src/ # 源代碼
lib/ # 如果作為一個模塊以供使用, 那么源代碼會放到這里
test/ # 測試
dist/ # 壓縮過的代碼, 用于生產(chǎn)環(huán)境, 前端庫經(jīng)常有這個目錄
package.json # 利用"main"指向入口文件
README.md # 項目說明
npm
npm作為包管理工具, 使用挺簡單的, 其實看一遍文檔就可以懂了. 文檔也很短.
Node.js已經(jīng)提供了模塊機制, 這就為依賴管理奠定了基礎(chǔ). 使用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> # 設(shè)置當前源為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, 關(guān)鍵字 -
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來進入提示, 依次輸入相應(yīng)的信息, 最后會為你生成一個package.json文件. 如果加上-y參數(shù), 則會直接生成package.json. 這些默認的值可以在npm config set init.<key> <value>設(shè)置, 而如果./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挺簡單的, 但是寫了這么多, 寫筆記的時間比看文檔的事件都長. 下次只記錄那些值得記錄的.