Node.js npm 詳解

1、npm簡介

安裝npm請閱讀我以前的文章Hello Node中npm安裝那一部分,不過只介紹了linux平臺,若是是其它平臺,有前輩寫了更加詳細的介紹。javascript

npm的全稱:Node Package Manager.html

####(1)通俗的理解前端

其實從字面意思就能夠理解這個產品有什麼做用翻譯爲「Node包管理器」。對,就是Node的包的一個管理工具,目前我嘗試的有java

  1. 下載並安裝包(npm install [pkg])
  2. 升級安裝包(npm update [pkg])
  3. 卸載安裝包(npm uninstall/rm [pkg]),能夠指定卸載包的版本號 ...

其實這些命令很簡單,經常使用的必須記住,不經常使用的查詢便可,這纔是比較好的學習知識方式。node

在終端輸入:python

//查看npm擁有的所有命令 $ npm --help $ npm help //查看某一個npm命令的詳細用法 $ npm <command> --help $ npm help <command> 

####(2)專業的解釋mysql

npm(Node Package Manager)是Node.js下的主流套件管理程式。它在Node.js v0.6.x版本以後,內建於Node系統。經過npm能夠協助開發者安裝、卸載、刪除、更新Node.js套件,而且能夠經過npm發佈本身的插件。linux

2、相似的產品

其實學習一個產品,能夠聯繫其它產品,可以更好的理解如今手頭的產品。第一次學習npm個人第一反應就是,很像linux/mac平臺的不少軟件,依賴管理的方式能夠參考maven...固然類似性能夠隨便聯想。c++

接下來,舉幾個例子吧,固然詳細瞭解能夠查baidu && google。git

  1. gem
  2. PyPL
  3. pear
  4. macPort
  5. Homebrew
  6. rem
  7. apt-get
  8. yum ...

是否是不少都很熟悉?這樣對於npm的認識就不用侷限於概念啦。

3、npm基礎功能

(1)npmrc文件介紹

首先介紹一下npmrc文件,這個文件是npm包管理器的配置文件。

與npmrc相關的三個文件:

  1. 用戶配置文件:~/.npmrc
  2. 全局配置文件:$PREFIX/npmrc
  3. npm內部配置文件:安裝npm的目錄下

下面仔細看一下npm config的配置。

(2)npm獲取配置的6種方式(優先級從高到低):

1.命令行參數

$ --proxy http://<server>:<port> 

2.環境變量

以"npmconfig"爲前綴的環境變量將會被認爲是npm的配置屬性。 像Maven鏡像的概念,方便通訊吧。

$ npm_config_proxy=http://<server>:<port> 

3.用戶配置文件

//查看文件路徑 $ npm config get userconfig //mac系統默認路徑 $HOME/.npmrc 

4.全局配置文件

//查看文件路徑 $ npm config get globalconfig //mac系統默認路徑 /usr/local/etc/npmrc 

3,4中輸入終端的效果如圖:

3,4在終端的結果

5.內置配置文件

安裝npm的目錄下的npmrc文件。

6.默認配置

若是前5條均未設置,npm會使用默認配置參數。

(4)npm install

「安裝指定包」:這個命令不難,可是也有須要注意的地方,就是安裝的模式有兩種,在後面會單獨講解。

若是不知道包的具體名稱,能夠在http://search.npmjs.org上進行搜索。

(5)npm uninstall

「卸載指定包」:在help的時候,會給你推薦npm rm 這個命令,uninstall會卸載掉包的依賴,rm。

####(6)npm ls

查看安裝的包清單,其實和linux的ls命令很像,能夠跟不少參數,詳情可使用

$ npm help ls 

####(7)npm search

搜索包的詳細信息,好比咱們搜索express試試。第一次搜索,會提示創建索引,須要耐心等待片刻,你們測試的時候不要就關掉啦終端。

npm WARN Building the local index for the first time, please be patient 

express包的搜索結果

其實看上去複雜,只是東西有點大,不過主要包含如下6個部分:

  1. 名稱
  2. 描述
  3. 做者
  4. 發佈時間
  5. 發佈版本號
  6. 關鍵字

####(8)npm update

更新安裝的包

更多API能夠查看官網:https://npmjs.org/doc/

4、版本號的知識。

在node.js中的package.json配置文件中,咱們須要配置版本號,好比0.1.2

第一位數字:主版本號

第二位數字:子版本號

第三位數字:補丁版本號

找到一個不錯的介紹軟件項目版本號的文章

軟件項目版本號的命名規則及格式

爲何要解釋這個呢?確定是有用,由於npm安裝的時候是能夠選擇版本號的,有點理解會比較好吧,至少我是這麼認爲的。

 

 

1、前言

好久以前就想系統的學習nodejs技術了,可是因爲不少事情,忙不太過來,今天晚上下定決心要入門這門技術,因此一口氣看完了《Node.js開發指南》和《Node.js中文文檔》,總算是真正入門了,接下來就總結一部分,剩下的只有明天再總結了。

2、Node.js簡介

一句話簡單說明一下node.js是什麼東西。

Node.js 是一個讓 JavaScript 運行在服務端的開發平臺。

3、Node.js的安裝

學習了Node.js,以爲若是在window下學習這門技術的話還太成熟,第三方的支持不太好,因此只介紹linux或者mac上面的安裝。node.js在window上面的安裝直接下載安裝包,一直下一步就能夠裝好,環境變量也會自動配置好,npm(node package manage)在新版本也會相應的裝上。

對於mac環境安裝也比較簡單,介紹兩種安裝方式。

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 | sh 

2.使用源碼編譯的方式(其實有方便的儘可能就避免麻煩的,嘿嘿)

下載地址:http://nodejs.org

執行典型的安裝命令便可(注意到/bin目錄,或者有configure文件的目錄)。

$ ./configure && make && sudo make install 

4、Node.js的多版本管理器n

下載地址:https://github.com/visionmedia/n

如上執行源碼安裝命令便可。

固然,若是你安裝了npm,就有更方便的方式,這也是很迷人的地方。

$ sudo npm install -g n 

接下來檢查一下安裝狀況。

$ n --version 

這樣就可使用自由切換使用node的版本了。用以下命令安裝指定版本的node。

$ n version 

下載後,會默認下載到:/usr/local/n/versions/目錄

若是你安裝後,再使用"$ n version"命令就是指定使用的默認版本號,也可使用「$ n use version xxx.js」來暫時使用某個node版本執行xxx.js文件。

5、萬事具有,只欠Hello Node.js

每一個語言入門均可以寫一個hello xxx,示好。

在node中,這個很簡單,只須要進入REPL模式,暫時不要管這個模式是什麼,咱們先使用。這個用截圖來直觀說明一下。

進入REPL模式的命令:

$ node 

接下來直接輸入:

console.log("hello node.js!"); 

就能夠在終端打印出:

>hello node.js! >undefined 

寫過js的應該對最後會輸出undefined並不吃驚,先能夠無論。

Mou icon

下面解釋一下REPL模式:

其實這個模式不用解釋,通過上面的例子應該就有直觀的認識啦,相似mysql、python等的shell交互的方式,可讓你輸入立刻就獲得反饋,輸出結果到屏幕上面。在node中能夠連續按兩次ctrl+c退出(可是python要使用exit()函數,很不舒服)。

上面是一種最簡單的方式,仍是介紹一種正規的方式吧,既然是js的運行平臺,咱們就寫一個js文件:hello.js,內容很簡單,以下:

console.log("hello node.js!"); console.log("%d\n", 60); 

在終端執行(注意要進入hello.js所在目錄哦):

$ node hello.js 

就能夠在終端直接輸出結果了。

爲何我加入了「console.log('%d\n', 60);」這一句呢?那是由於這能夠測試出其實能夠用c語言printf的方式來寫console.log()。

6、Node.js終於來到了瀏覽器

前面的例子都是在控制檯裏面的,沒什麼意思,咱們接下來寫一個咱們典型的B/S訪問的方式。固然這就離不開HTTP了,查看了一下node的源碼,新版本默認是http 1.1,支持http和https這兩種協議。

咱們先建一個http.js文件,裏面的內容對於後臺的開發人員就很熟悉了。

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."); 

以上代碼監聽的port:8888,這其實就是創建了一個request,咱們在瀏覽器地址欄中輸入:http://localhost:8888/ 便可以訪問咱們打印的內容。

咱們先在終端運行後臺服務:

$ node http.js 

Mou icon

咱們來分析一下這個簡單的程序,其實從require的加載方式咱們並不陌生,這是如今模塊加載在前端廣泛使用的函數名,那麼爲何咱們的js代碼就可以這樣來請求和訪問呢?咱們來簡單的看看源碼的解析。

1. 首先咱們先看看源碼的http.js文件。

var Server = exports.Server = server.Server; function createServer() { return new Server(requestListener) }; 

在這個文件中,咱們知道createServer()方法其實返回的就是Server類,這個類是由server這個實例來的。

2. 接下來咱們再追蹤一下_http_server.js文件。

這個要問怎麼找到這些文件的,實際上是憑直覺和猜想,再加上模塊化的調試方法,能夠找到http.js文件的加載模塊,就能夠找到相應的文件了。

function requestListener() {}; function connectionListener(socket) {} Server.prototype.setTimeout = function(msecs, callback) {}; 

再這個文件中,咱們能夠看出和Socket原理差很少,使用定時器來實現端口的監聽,可是在源碼中能夠找到主定時器,這個概念來源於遊戲開發,在全局設置定時器,這樣大大提高了性能,不得不佩服做者的才能。

3. 那麼咱們node底層是c/c++來實現的,咱們能夠追蹤一下node的啓動。

咱們先找到c語言的main文件,後來發現好多node_開頭的,大楷就是系統和行一點的文件了,在node_main.cc文件中發現了:node::Start(argc, argv);函數,可是找不到具體實現,那麼就確定是在依賴文件中,經過頭文件的聲明,找到了,其實實現位於node.cc文件。

4. node.cc文件來看node啓動流程。

函數大體的執行順序爲:

int Start(int argc, char** argv)
V8::Initialize();
    CreateEnvironment() //建立當前環境
    SetupProcessObject() //啓動當前環境的進程
    Load() //加載當前環境
    context() //引用上下文
    uv_run //開始異步事件運行
    RunAtExit //刪除異步事件鏈表

上面能夠看出其實就是經過一系列初始化,最後達到平臺的創建。

5. module的加載實質

其實咱們通過上面的分析,咱們大體知道的node的構成,那麼咱們可以在node.js(猜測:這個js文件是c和js溝通的橋樑)中,發現傳入了process對象。源碼結構以下:

(function(process) {}); //本地模塊的加載接口 NativeModule.require(); 

咱們來看一看根據process來綁定c語言的模塊。

var HTTPParser = process.binding("http_parser").HTTPParser; 

是否是就很清晰啦,接下來咱們看看模塊是怎麼註冊的。

//如今產生的插件會放置在node_module文件夾下應該很清晰了 //定義了一個指針結構 node_module_struct* mod //註冊本身的模塊 mod->register_func(Handle<Object> target) //爲註冊的模塊設置一個上下文 mod->register_context_func //最後加載到模塊緩存,這裏也是實現延遲加載的本質 cache->Set(module, exports) 

在模塊註冊後,還須要作一些準備工做纔可以真正的加載到咱們的js文件。

//node.cc文件中執行綁定 static void Binding(const FunctionCallbackInfo<Value>& args); //node_javascript.cc文件中會定義你的js void DefineJavaScript(Handle<Object> target); 

6. 在module.js文件中,獲得真正的js文件的加載,平臺調用。

在這裏做者的module數據結構設置得比較簡單,拋去其它得留下結構以下:

module: { id: "", parent: [], export: {}, filename, children: [] } 

這樣咱們這個http程序就可以很好得解釋啦。其實知道了原理後面得知識就是看看api和寫法了。太晚啦,睡覺覺啦 =_=...後續...

 

 

 

 

安裝Node和npm前半部分的配置能夠參考以前個人兩篇文章:

  1. Hello Node
  2. Node npm 詳解(1)

4、本地模式和全局模式

若是你瞭解環境變量裏面的,用戶變量和系統變量。能夠作一個類比進行理解。固然,windows上面的環境變量概念比較好理解。

1. 本地模式

本地模式下安裝包的特色

  • 不會寫入PATH變量(也就是環境變量,沒法在全局引用該安裝包,不能在終端直接使用)
  • 可以在不一樣的node_modules目錄,安裝不一樣版本的安裝包
  • 可以經過require()來引入安裝包

使用「npm install [@]」安裝的包,默認會安裝在當前目錄的「node_modules」目錄下(若是沒有該目錄,在執行命令的時候,會自動幫你建立)。

//專業的寫法 ./node_modules 

(1)默認採用本地模式安裝

npm install <pkg> 

(2)信息寫入package.json文件

npm install <pkg> --save 

這個命令在安裝包的同時,將信息寫入package.json。

@version表示指定安裝包的版本號,是可選項目,默認安裝最新版本。

項目路徑中若是有package.json文件,使用npm install方法就能夠根據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"參數啦。

$ npm set global=true $ npm config set global=true 

npm set / npm config set與npm get / npm config get的區別和聯繫單獨寫吧。其實不難,只是須要實驗才能得出結果,這裏區別很細節。

準備把文章拆分紅幾篇,寫得詳細了一點,這裏寫的話篇幅就太長了。

相關文章
相關標籤/搜索