在使用 nodejs 開發中我們都免不了要去安裝一些第三方模塊。
那么你或多或少的遇到過以下一些問題
再繼續閱讀之前,我們先來弄清楚一個概念。
npm install --global xxx
屬於全局安裝
npm install xxx
屬於本地安裝
安裝的模塊太多項目太臃腫,模塊沒能復用
你寫一個項目 A 需要安裝一個 express 模塊,又開發一個項目 B 又需要安裝一個 express 模塊
項目中依賴包太多,文件過多,模塊沒法復用,各種問題浮現
由於 安裝的依賴包過多(而且依賴包嵌套依賴包)
,如果一個項目依賴多的話,(比如依賴 gulp
系列 或 grunt
系列的項目構模塊)那么一個項目可以說輕輕松松上百兆
。如果想給想項目更換一個目錄,都發現是痴心妄想了。(基本都是1-10KB的小文本文件組成了一個100多MB的項目,那得有多少個文件啊!想想如果像java那樣,模塊都是以jar包存在的壓縮歸檔文件可能也好一點)
。更別提部署了。
其實這里面的代碼也就是 幾十KB到1兆
是我們自己寫的代碼。這些文件想實現 復制,移動,部署是很方面的。
給部署帶來的困擾
如果你部署過 node 項目到遠程服務器,node_modules 目錄的上傳將是一件恐怖的事情
NODE_PATH 出現,模塊復用,最佳實踐方案
NODE_PATH
是干什么的呢?
操作系統中都會有一個PATH
環境變量,想必大家都知道,當系統調用一個命令的時候,就會在PATH變量中注冊的路徑中尋找,如果注冊的路徑中有就調用,否則就提示命令沒找到。
-> export PATH=$PATH: # 將 /usr/bin 追加到 PATH 變量中 -> export NODE_PATH="/usr/lib/node_modules;/usr/local/lib/node_modules" #指定 NODE_PATH 變量
那 NODE_PATH
就是NODE
中用來尋找模塊所提供的路徑注冊環境變量
。我們可以使用上面的方法指定NODE_PATH環境變量。並且用;
分割多個不同的目錄。
加載時機
關於 node 的包加載機制我就不在這里廢話了。NODE_PATH中的路徑被遍歷是發生在
從項目的根位置遞歸搜尋 node_modules
目錄,直到文件系統根目錄的 node_modules
,如果還沒有查找到指定模塊的話,就會去 NODE_PATH中注冊的路徑中查找
。
解決問題
基於 nodejs 的包加載路徑搜索算法,我們可以 采用全局安裝的方式,將我們的包安裝到全局。
這樣,我們的項目就可以共享全局中的依賴包。
了解全局
npm root -g
查看在你的系統中全局的路徑。
我們也可以通過npm config ls -l | grep prefix
(*nix) 系統中
或是npm config get prefix
來查看全局路徑。
是的 prefix
字段就是全局base path
怎么設置全局路徑呢?
# in *nix npm config set prefix /path/to/global # in windows npm config set prefix C:\\Users\\pc\\global
求同存異,解決模塊版本問題
差異性的解決方法
如果 項目A 使用了,express的3.x版本,項目B 使用了 express的4.x版本,那這種情況該怎么辦呢?
可以將 NODE_PATH 指定的位置中存放 express的4.x版本,再將 項目B的 node_modules
目錄中放置 3.x 版本。
這樣就解決了模塊版本差異性問題。
所以說,兩種安裝方式我們並不是只是用其中的一種,他們可以結合使用,根據 nodejs 的包加載機制,我們可以靈活使用。
部署不再是問題
在部署之前,我們可以將我們項目的所有可以全局安裝的模塊,都以全局的安裝方式安裝到服務器中。接下來我們就可以輕松,上傳我們的項目到服務器中了。這樣上傳也會變得的很快。
然后配置我們的 NODE_PATH
環境變量。怎么配置上面也談過,這里就不用多說了。(因為項目的部署方式多種多樣,所以具體情況可以自行決定。)
本人是使用 PM2 部署管理Nodejs項目,所以我寫在 配置文件中。
帶來的問題
是的這種方式也有缺點。因為在使用 --global
參數的時候 --save
或 --save-dev
參數是無效的。
這樣就帶來一個問題。此時 package.json
中的 dependencies
, devDependencies
將無法享受到npm自動更新帶來的便利,不使用 dependencies
, devDependencies
字段對我們的項目管理來說是不可接受的。
如何解決
我有一個不是很優雅地解決方法,但是也算是解決了這個問題,希望有更好解決辦法的同學給我留言。
我寫了一個小工具(npmafter
),它的使用方法很簡單, 它是跨平台的。兼容(Mac,Windows,Linux)。(我沒有發布到github上,因為感覺會有更好的辦法)
$ npm install -g http://yinchangsheng-blog.qiniudn.com/blog/nodejs/npmafter.tgz # install # 然后我們安裝任何模塊就可以這樣 $ npm install express -g | npmafter $ npm install request q -g | npmafter --save $ npm install mocha chai -g | npmafter --save-dev
是的 package.json
文件就會得到更新。
好的,如果你不糾結這個問題那么這個問題就算是解決了。
使用 NODE_PATH
可以很好的解決項目開發部署的問題。