Node.js npm 详解
一、npm簡介
安裝npm請閱讀我之前的文章Hello Node中npm安裝那一部分,不過只介紹了linux平臺,如果是其它平臺,有前輩寫了更加詳細的介紹。
npm的全稱:Node Package Manager.
####(1)通俗的理解
其實從字面意思就可以理解這個產(chǎn)品有什么作用翻譯為“Node包管理器”。對,就是Node的包的一個管理工具,目前我嘗試的有
其實這些命令很簡單,常用的必須記住,不常用的查詢即可,這才是比較好的學習知識方式。
在終端輸入:
//查看npm擁有的全部命令 $ npm --help $ npm help //查看某一個npm命令的詳細用法 $ npm <command> --help $ npm help <command>####(2)專業(yè)的解釋
npm(Node Package Manager)是Node.js下的主流套件管理程式。它在Node.js v0.6.x版本之后,內(nèi)建于Node系統(tǒng)。通過npm可以協(xié)助開發(fā)者安裝、卸載、刪除、更新Node.js套件,并且可以通過npm發(fā)布自己的插件。
二、類似的產(chǎn)品
其實學習一個產(chǎn)品,可以聯(lián)系其它產(chǎn)品,能夠更好的理解現(xiàn)在手頭的產(chǎn)品。第一次學習npm我的第一反應就是,很像linux/mac平臺的很多軟件,依賴管理的方式可以參考maven...當然相似性可以隨便聯(lián)想。
接下來,舉幾個例子吧,當然詳細了解可以查baidu && google。
是不是很多都很熟悉?這樣對于npm的認識就不用局限于概念啦。
三、npm基礎功能
(1)npmrc文件介紹
首先介紹一下npmrc文件,這個文件是npm包管理器的配置文件。
與npmrc相關的三個文件:
下面仔細看一下npm config的配置。
(2)npm獲取配置的6種方式(優(yōu)先級從高到低):
1.命令行參數(shù)
$ --proxy http://<server>:<port>2.環(huán)境變量
以"npmconfig"為前綴的環(huán)境變量將會被認為是npm的配置屬性。 像Maven鏡像的概念,方便通信吧。
$ npm_config_proxy=http://<server>:<port>3.用戶配置文件
//查看文件路徑 $ npm config get userconfig//mac系統(tǒng)默認路徑4.全局配置文件
//查看文件路徑 $ npm config get globalconfig//mac系統(tǒng)默認路徑 /usr/local/etc/npmrc3,4中輸入終端的效果如圖:
5.內(nèi)置配置文件
安裝npm的目錄下的npmrc文件。
6.默認配置
如果前5條均未設置,npm會使用默認配置參數(shù)。
(4)npm install
“安裝指定包”:這個命令不難,但是也有需要注意的地方,就是安裝的模式有兩種,在后面會單獨講解。
如果不知道包的具體名稱,可以在http://search.npmjs.org上進行搜索。
(5)npm uninstall
“卸載指定包”:在help的時候,會給你推薦npm rm?這個命令,uninstall會卸載掉包的依賴,rm。
####(6)npm ls
查看安裝的包清單,其實和linux的ls命令很像,可以跟很多參數(shù),詳情可以使用
$ npm help ls####(7)npm search
搜索包的詳細信息,比如我們搜索express試試。第一次搜索,會提示建立索引,需要耐心等待片刻,大家測試的時候不要就關掉啦終端。
npm WARN Building the local index for the first time, please be patient其實看上去復雜,只是東西有點大,不過主要包含以下6個部分:
####(8)npm update
更新安裝的包
更多API可以查看官網(wǎng):https://npmjs.org/doc/
四、版本號的知識。
在node.js中的package.json配置文件中,我們需要配置版本號,比如0.1.2
第一位數(shù)字:主版本號
第二位數(shù)字:子版本號
第三位數(shù)字:補丁版本號
找到一個不錯的介紹軟件項目版本號的文章
軟件項目版本號的命名規(guī)則及格式
為什么要解釋這個呢?肯定是有用,因為npm安裝的時候是可以選擇版本號的,有點理解會比較好吧,至少我是這么認為的。
?
?
一、前言
很久之前就想系統(tǒng)的學習nodejs技術了,但是由于很多事情,忙不太過來,今天晚上下定決心要入門這門技術,所以一口氣看完了《Node.js開發(fā)指南》和《Node.js中文文檔》,總算是真正入門了,接下來就總結一部分,剩下的只有明天再總結了。
二、Node.js簡介
一句話簡單說明一下node.js是什么東西。
Node.js 是一個讓 JavaScript 運行在服務端的開發(fā)平臺。
三、Node.js的安裝
學習了Node.js,覺得如果在window下學習這門技術的話還太成熟,第三方的支持不太好,所以只介紹linux或者mac上面的安裝。node.js在window上面的安裝直接下載安裝包,一直下一步就可以裝好,環(huán)境變量也會自動配置好,npm(node package manage)在新版本也會相應的裝上。
對于mac環(huán)境安裝也比較簡單,介紹兩種安裝方式。
1.homebrew(注意一直使用admin權限吧,大多都是權限文件夾,可以在終端開始使用sudo -s命令來一直使用admin權限)
$ sudo brew install node這樣下載完了就算安裝上了,我們可以來檢測一下你的安裝(軟件配置必須要的步驟)。
# 查看node版本號 $ node -v # 查看npm版本號和清單 $ npm -v && npm list如果npm沒有安裝上,那么可以使用以下命令安裝。
$ sudo curl http://npmjs.org/install.sh | sh2.使用源碼編譯的方式(其實有方便的盡量就避免麻煩的,嘿嘿)
下載地址:http://nodejs.org
執(zhí)行典型的安裝命令即可(注意到/bin目錄,或者有configure文件的目錄)。
$ ./configure && make && sudo make install四、Node.js的多版本管理器n
下載地址:https://github.com/visionmedia/n
如上執(zhí)行源碼安裝命令即可。
當然,如果你安裝了npm,就有更方便的方式,這也是很迷人的地方。
$ sudo npm install -g n接下來檢查一下安裝情況。
$ n --version這樣就可以使用自由切換使用node的版本了。用如下命令安裝指定版本的node。
$ n version下載后,會默認下載到:/usr/local/n/versions/目錄
如果你安裝后,再使用"$ n version"命令就是指定使用的默認版本號,也可以使用“$ n use version xxx.js”來暫時使用某個node版本執(zhí)行xxx.js文件。
五、萬事具備,只欠Hello Node.js
每個語言入門都可以寫一個hello xxx,示好。
在node中,這個很簡單,只需要進入REPL模式,暫時不要管這個模式是什么,我們先使用。這個用截圖來直觀說明一下。
進入REPL模式的命令:
$ node接下來直接輸入:
console.log("hello node.js!");就可以在終端打印出:
>hello node.js! >undefined寫過js的應該對最后會輸出undefined并不吃驚,先可以不管。
下面解釋一下REPL模式:
其實這個模式不用解釋,經(jīng)過上面的例子應該就有直觀的認識啦,類似mysql、python等的shell交互的方式,可以讓你輸入馬上就得到反饋,輸出結果到屏幕上面。在node中可以連續(xù)按兩次ctrl+c退出(但是python要使用exit()函數(shù),很不舒服)。
上面是一種最簡單的方式,還是介紹一種正規(guī)的方式吧,既然是js的運行平臺,我們就寫一個js文件:hello.js,內(nèi)容很簡單,如下:
console.log("hello node.js!"); console.log("%d\n", 60);在終端執(zhí)行(注意要進入hello.js所在目錄哦):
$ node hello.js就可以在終端直接輸出結果了。
為什么我加入了“console.log('%d\n', 60);”這一句呢?那是因為這可以測試出其實可以用c語言printf的方式來寫console.log()。
六、Node.js終于來到了瀏覽器
前面的例子都是在控制臺里面的,沒什么意思,我們接下來寫一個我們典型的B/S訪問的方式。當然這就離不開HTTP了,查看了一下node的源碼,新版本默認是http 1.1,支持http和https這兩種協(xié)議。
我們先建一個http.js文件,里面的內(nèi)容對于后臺的開發(fā)人員就很熟悉了。
var http = require("http"); http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}); res.write("<h1>Node.js</h1>"); res.end("<p>Hello Node.js</p>"); }).listen(8888); console.log("HTTP server is listening at port 8888.");以上代碼監(jiān)聽的port:8888,這其實就是建立了一個request,我們在瀏覽器地址欄中輸入:http://localhost:8888/?即可以訪問我們打印的內(nèi)容。
我們先在終端運行后臺服務:
$ node http.js我們來分析一下這個簡單的程序,其實從require的加載方式我們并不陌生,這是現(xiàn)在模塊加載在前端普遍使用的函數(shù)名,那么為什么我們的js代碼就能夠這樣來請求和訪問呢?我們來簡單的看看源碼的解析。
1. 首先我們先看看源碼的http.js文件。
var Server = exports.Server = server.Server; function createServer() { return new Server(requestListener) };在這個文件中,我們知道createServer()方法其實返回的就是Server類,這個類是由server這個實例來的。
2. 接下來我們再追蹤一下_http_server.js文件。
這個要問怎么找到這些文件的,其實是憑直覺和猜測,再加上模塊化的調(diào)試方法,可以找到http.js文件的加載模塊,就可以找到相應的文件了。
function requestListener() {}; function connectionListener(socket) {} Server.prototype.setTimeout = function(msecs, callback) {};再這個文件中,我們可以看出和Socket原理差不多,使用定時器來實現(xiàn)端口的監(jiān)聽,但是在源碼中可以找到主定時器,這個概念來源于游戲開發(fā),在全局設置定時器,這樣大大提升了性能,不得不佩服作者的才能。
3. 那么我們node底層是c/c++來實現(xiàn)的,我們可以追蹤一下node的啟動。
我們先找到c語言的main文件,后來發(fā)現(xiàn)好多node_開頭的,大楷就是系統(tǒng)和行一點的文件了,在node_main.cc文件中發(fā)現(xiàn)了:node::Start(argc, argv);函數(shù),但是找不到具體實現(xiàn),那么就肯定是在依賴文件中,通過頭文件的聲明,找到了,其實實現(xiàn)位于node.cc文件。
4. node.cc文件來看node啟動流程。
函數(shù)大致的執(zhí)行順序為:
int Start(int argc, char** argv) V8::Initialize();CreateEnvironment() //創(chuàng)建當前環(huán)境SetupProcessObject() //啟動當前環(huán)境的進程Load() //加載當前環(huán)境context() //引用上下文uv_run //開始異步事件運行RunAtExit //刪除異步事件鏈表上面可以看出其實就是通過一系列初始化,最后達到平臺的建立。
5. module的加載實質(zhì)
其實我們經(jīng)過上面的分析,我們大致知道的node的構成,那么我們能夠在node.js(猜想:這個js文件是c和js溝通的橋梁)中,發(fā)現(xiàn)傳入了process對象。源碼結構如下:
(function(process) {}); //本地模塊的加載接口 NativeModule.require();我們來看一看根據(jù)process來綁定c語言的模塊。
var HTTPParser = process.binding("http_parser").HTTPParser;是不是就很清晰啦,接下來我們看看模塊是怎么注冊的。
//現(xiàn)在產(chǎn)生的插件會放置在node_module文件夾下應該很清晰了 //定義了一個指針結構 node_module_struct* mod //注冊自己的模塊 mod->register_func(Handle<Object> target) //為注冊的模塊設置一個上下文 mod->register_context_func //最后加載到模塊緩存,這里也是實現(xiàn)延遲加載的本質(zhì) cache->Set(module, exports)在模塊注冊后,還需要做一些準備工作才能夠真正的加載到我們的js文件。
//node.cc文件中執(zhí)行綁定 static void Binding(const FunctionCallbackInfo<Value>& args); //node_javascript.cc文件中會定義你的js void DefineJavaScript(Handle<Object> target);6. 在module.js文件中,得到真正的js文件的加載,平臺調(diào)用。
在這里作者的module數(shù)據(jù)結構設置得比較簡單,拋去其它得留下結構如下:
module: {id: "",parent: [],export: {},filename,children: [] }這樣我們這個http程序就能夠很好得解釋啦。其實知道了原理后面得知識就是看看api和寫法了。太晚啦,睡覺覺啦 =_=...后續(xù)...
?
?
?
?
安裝Node和npm前半部分的配置可以參考之前我的兩篇文章:
四、本地模式和全局模式
如果你了解環(huán)境變量里面的,用戶變量和系統(tǒng)變量。可以做一個類比進行理解。當然,windows上面的環(huán)境變量概念比較好理解。
1. 本地模式
本地模式下安裝包的特點
- 不會寫入PATH變量(也就是環(huán)境變量,無法在全局引用該安裝包,不能在終端直接使用)
- 能夠在不同的node_modules目錄,安裝不同版本的安裝包
- 能夠通過require()來引入安裝包
使用“npm install?[@]”安裝的包,默認會安裝在當前目錄的“node_modules”目錄下(如果沒有該目錄,在執(zhí)行命令的時候,會自動幫你創(chuàng)建)。
//專業(yè)的寫法 ./node_modules(1)默認采用本地模式安裝
npm install <pkg>(2)信息寫入package.json文件
npm install <pkg> --save這個命令在安裝包的同時,將信息寫入package.json。
@version表示指定安裝包的版本號,是可選項目,默認安裝最新版本。
項目路徑中如果有package.json文件,使用npm install方法就可以根據(jù)dependencies配置安裝所有的依賴包。
如果這樣配置,當代碼提交到github時,就不用提交node_modules這個文件夾。
2. 全局模式
全局模式安裝包的特點
- 不需要重復安裝
- 不能使用require()引入
- 會寫入PATH,并建立軟鏈接,使用命令行的方式使用
- 不方便指定特定的版本運行
(1)采用全局模式安裝
npm install -g <pkg>(3)在mac中全局的目錄
//安裝包所在目錄 /usr/local/lib/node_modules/ //運行命令的軟鏈接所在目錄 /usr/local/bin(4)查看安裝包路徑
//查看當前包的安裝路徑 npm root //查看全局的包的安裝路徑 npm root -g(5)設置全局模式安裝目錄
//設置后,以全局模式將會安裝在此目錄中,不過需要手動加入PATH,切記 npm config set prefix <global dir> //設置npm緩存文件的存放路徑 npm config set cache <cache dir>(6)查看默認模式
//默認返回:false $ npm get global $ npm config get global(7)設置為默認以全局模式安裝,就不用每次加"-g"參數(shù)啦。
$ npm set global=true $ npm config set global=truenpm set / npm config set與npm get / npm config get的區(qū)別和聯(lián)系單獨寫吧。其實不難,只是需要實驗才能得出結果,這里區(qū)別很細節(jié)。
準備把文章拆分成幾篇,寫得詳細了一點,這里寫的話篇幅就太長了。
轉載于:https://www.cnblogs.com/libin-1/p/5907175.html
總結
以上是生活随笔為你收集整理的Node.js npm 详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转] 三种Python下载url并保存
- 下一篇: 关于Cocos2d-x的专属数据类型