關於npm

1、npm簡介

npm全稱爲Node Package Manager,是一個基於Node.js的包管理器,也是整個Node.js社區最流行、支持的第三方模塊最多的包管理器。css

npm的初衷:vue

JavaScript開發人員更容易分享和重用代碼。node

npm的使用場景:webpack

  • 容許用戶獲取第三方包並使用。git

  • 容許用戶將本身編寫的包或命令行程序進行發佈分享。github

npm版本查詢 npm -vweb

npm安裝:正則表達式

一、安裝nodejsexpress

因爲新版的nodejs已經集成了npm,因此可直接經過輸入npm -v來測試是否成功安裝。npm

二、使用npm命令來升級npm: npm install npm -g

2、npm的工做原理:

包和模塊

什麼是包(package)?

包是描述一個文件或一個目錄。一個包的配置一般由如下構成:

  • 一個文件夾包含一個package.json配置文件。
  • 包含(含有package.json文件的文件夾)的Gzip壓縮文件。
  • 解析gzip的url
  • 爲註冊表添加@的url 信息

注意的是即便你歷來沒有在註冊中心發佈你的公共包,你可能仍然能夠獲得不少全部這些package, 使用npm的好處:

  • 若是你只是計劃想寫增長一個節點或/。
  • 若是你安裝它也但願在其餘地方分紅一個tarball後進行包裝

2.什麼是模塊(module)?

模板是經過配置文件中的一個dom節點進行包含一個或多個包。一般通常由包和配置文件以及相關模塊程序構成完成一個或多個業務功能操做。

一個模塊能夠在node . js 程序中裝滿任何的require()任何。 如下是全部事物加載模塊的例子 :

  • 一個文件夾package.json文件包含一個main字段。

  • 一個文件夾index.js文件。

  • 一個JavaScript文件。

3.npm的包和模塊的關係:

通常來講在js程序中使用require加載它們的模塊在節點中進行配置npm包,一個模塊不必定是一個包。

例如,一些cli包, js程序節點中只包含一個可執行的 命令行界面,不提供main字段。 那麼這些包不是模塊。

幾乎全部npm包(至少,那些節點計劃)包含許多模塊在他們(由於每一個文件加載require()是一個模塊)。

幾乎全部的npm包都關聯着多個模塊,由於每一個文件都使用require()加載一個模塊。

從module加載文件中的上下文node節點。如:var req = require('request')。咱們可能會說,「request模塊賦值給req這個變量」。

4.npm的生態系統:

package.json文件定義的是包。

node_modules文件夾是存儲模塊的地方。便於js查找模塊。

若是建立一個node_modules/foo.js文件,經過var f=require('foo.js')進行加載模塊。由於它沒有package.json文件因此foo.js不是一個包。

若是沒有建立index.js包或者package.json文件"main"字段,即便是在安裝node_modules,由於它沒有require()因此它不是一個模塊。

使用

npm init

npm init 用來初始化生成一個新的 package.json 文件。它會向用戶提問一系列問題,若是你以爲不用修改默認配置,一路回車就能夠了。

若是使用了 -f(表明force)、-y(表明yes),則跳過提問階段,直接生成一個新的 package.json 文件。

$ npm init -y
複製代碼

npm set

npm set 用來設置環境變量

$ npm set init-author-name 'Your name'
$ npm set init-author-email 'Your email'
$ npm set init-author-url 'http://yourdomain.com'
$ npm set init-license 'MIT'複製代碼

上面命令等於爲 npm init 設置了默認值,之後執行 npm init 的時候,package.json 的做者姓名、郵件、主頁、許可證字段就會自動寫入預設的值。這些信息會存放在用戶主目錄的 ~/.npmrc文件,使得用戶不用每一個項目都輸入。若是某個項目有不一樣的設置,能夠針對該項目運行 npm config。

npm info

npm info 命令能夠查看每一個模塊的具體信息。好比,查看 underscore 模塊的信息。

$ npm info underscore
複製代碼

上面命令返回一個 JavaScript 對象,包含了 underscore 模塊的詳細信息。這個對象的每一個成員,均可以直接從 info 命令查詢。

$ npm info underscore description

$ npm info underscore homepage

$ npm info underscore version

複製代碼

npm search

npm search 命令用於搜索 npm 倉庫,它後面能夠跟字符串,也能夠跟正則表達式。

$ npm search <搜索詞>
複製代碼

npm list

npm list 命令以樹形結構列出當前項目安裝的全部模塊,以及它們依賴的模塊。

$ npm list

# 加上 global 參數,會列出全局安裝的模塊
$ npm list -global

# npm list 命令也能夠列出單個模塊
$ npm list underscore
複製代碼

npm install

使用 npm 安裝包的命令格式爲:

npm [install/i] [package_name]

本地模式和全局模式

npm 在默認狀況下會從 npmjs.org 搜索或下載包,將包安裝到當前目錄的 node_modules 子目錄下。

若是你熟悉 Ruby 的 gem 或者 Python 的 pip,你會發現 npm 與它們的行爲不一樣,gem 或 pip 老是以全局模式安裝,使包能夠供全部的程序使用,而 npm 默認會把包安裝到當前目錄下。這反映了 npm 不一樣的設計哲學。若是把包安裝到全局,能夠提供程序的重複利用程度,避免一樣的內容的多分副本,但壞處是難以處理不一樣的版本依賴。若是把包安裝到當前目錄,或者說本地,則不會有不一樣程序依賴不一樣版本的包的衝突問題,同時還減輕了包做者的 API 兼容性壓力,但缺陷則是同一個包可能會被安裝許屢次。

咱們在使用 supervisor 的時候使用了 npm install -g supervisor 命令,就是以全局模式安裝 supervisor 。

這裏注意一點的就是,supervisor 必須安裝到全局,若是你不安裝到全局,錯誤命令會提示你安裝到全局。若是不想安裝到默認的全局,也能夠本身修改全局路徑到當前路徑 npm config set prefix "路徑" 安裝完之後就能夠用 supervisor 來啓動服務了。

supervisor 能夠幫助你實現這個功能,它會監視你對代碼的驅動,並自動重啓 Node.js 。

通常來講,全局安裝只適用於工具模塊,好比 eslint 和 gulp 。關於使用全局模式,多數時候並非由於許多程序都有可能用到了它,爲了減小多重副本而使用全局模式,而是由於本地模式不會註冊 PATH 環境變量。

「本地安裝」指的是將一個模塊下載到當前項目的 node_modules 子目錄,而後只有在項目目錄之中,才能調用這個模塊。

# 本地安裝
$ npm install <package name>

# 全局安裝
$ sudo npm install -global <package name>
$ sudo npm install -g <package name>
複製代碼

npm install 也支持直接輸入 Github 代碼庫地址。

$ npm install git://github.com/package/path.git
$ npm install git://github.com/package/path.git#0.1.0
複製代碼

安裝以前,npm install 會先檢查,node_modules 目錄之中是否已經存在指定模塊。若是存在,就再也不從新安裝了,即便遠程倉庫已經有了一個新版本,也是如此。

果你但願,一個模塊無論是否安裝過, npm 都要強制從新安裝,可使用 -f 或 --force 參數。

$ npm install <packageName> --force

複製代碼

安裝不一樣版本

install 命令老是安裝模塊的最新版本,若是要安裝模塊的特定版本,能夠在模塊名後面加上 @ 和版本號。

$ npm install sax@latest
$ npm install sax@0.1.1
$ npm install sax@">=0.1.0 <0.2.0"
複製代碼

install 命令可使用不一樣參數,指定所安裝的模塊屬於哪種性質的依賴關係,即出如今 packages.json 文件的哪一項中。

–save:模塊名將被添加到 dependencies,能夠簡化爲參數-S。
–save-dev:模塊名將被添加到 devDependencies,能夠簡化爲參數-D。

$ npm install sax --save
$ npm install node-tap --save-dev
# 或者
$ npm install sax -S
$ npm install node-tap -D
複製代碼

dependencies 依賴

這個能夠說是咱們 npm 核心一項內容,依賴管理,這個對象裏面的內容就是咱們這個項目所依賴的 js 模塊包。下面這段代碼表示咱們依賴了 markdown-it 這個包,版本是 ^8.1.0 ,表明最小依賴版本是 8.1.0 ,若是這個包有更新,那麼當咱們使用 npm install 命令的時候,npm 會幫咱們下載最新的包。當別人引用咱們這個包的時候,包內的依賴包也會被下載下來。

"dependencies": {
    "markdown-it": "^8.1.0"
}
複製代碼

devDependencies 開發依賴

在咱們開發的時候會用到的一些包,只是在開發環境中須要用到,可是在別人引用咱們包的時候,不會用到這些內容,放在 devDependencies 的包,在別人引用的時候不會被 npm 下載。

"devDependencies": {
    "autoprefixer": "^6.4.0",0", "babel-preset-es2015": "^6.0.0", "babel-preset-stage-2": "^6.0.0", "babel-register": "^6.0.0", "webpack": "^1.13.2", "webpack-dev-middleware": "^1.8.3", "webpack-hot-middleware": "^2.12.2", "webpack-merge": "^0.14.1", "highlightjs": "^9.8.0" } 複製代碼

當你有了一個完整的 package.json 文件的時候,就可讓人一眼看出來,這個模塊的基本信息,和這個模塊所須要依賴的包。咱們能夠經過 npm install 就能夠很方便的下載好這個模塊所須要的包。

npm install 默認會安裝 dependencies 字段和 devDependencies 字段中的全部模塊,若是使用 --production 參數,能夠只安裝 dependencies 字段的模塊。

$ npm install --production
# 或者
$ NODE_ENV=production npm install
複製代碼

一旦安裝了某個模塊,就能夠在代碼中用 require 命令加載這個模塊。

var backbone = require('backbone')
console.log(backbone.VERSION)

複製代碼

npm run

npm 不只能夠用於模塊管理,還能夠用於執行腳本。package.json 文件有一個 scripts 字段,能夠用於指定腳本命令,供 npm 直接調用。

package.json

{
  "name": "myproject",
  "devDependencies": {
    "jshint": "latest",
    "browserify": "latest",
    "mocha": "latest"
  },
  "scripts": {
    "lint": "jshint **.js",
    "test": "mocha test/"
  }
}

複製代碼

scripts 腳本

顧名思義,就是一些腳本代碼,能夠經過 npm run script-key 來調用,例如在這個 package.json 的文件夾下使用 npm run dev 就至關於運行了 node build/dev-server.js 這一段代碼。使用 scripts 的目的就是爲了把一些要執行的代碼合併到一塊兒,使用 npm run 來快速的運行,方便省事。 npm run 是 npm run-script 的縮寫,通常都使用前者,可是後者能夠更好的反應這個命令的本質。

/ 腳本
"scripts": {
    "dev": "node build/dev-server.js",
    "build": "node build/build.js",
    "docs": "node build/docs.js",
    "build-docs": "npm run docs & git checkout gh-pages & xcopy /sy dist\\* . & git add . & git commit -m 'auto-pages' & git push & git checkout master",
    "build-publish": "rmdir /S /Q lib & npm run build &git add . & git commit -m auto-build & npm version patch & npm publish & git push",
    "lint": "eslint --ext .js,.vue src"
}

複製代碼

npm run 若是不加任何參數,直接運行,會列出 package.json 裏面全部能夠執行的腳本命令。 npm 內置了兩個命令簡寫, npm test 等同於執行 npm run test,npm start 等同於執行 npm run start。

"build": "npm run build-js && npm run build-css"
複製代碼

上面的寫法是先運行 npm run build-js ,而後再運行 npm run build-css ,兩個命令中間用 && 鏈接。若是但願兩個命令同時平行執行,它們中間能夠用 & 鏈接。

寫在 scripts 屬性中的命令,也能夠在 node_modules/.bin 目錄中直接寫成 bash 腳本。下面是一個 bash 腳本。

pre- 和 post- 腳本

npm run 爲每條命令提供了 pre- 和 post- 兩個鉤子(hook)。以 npm run lint 爲例,執行這條命令以前,npm 會先查看有沒有定義 prelint 和 postlint 兩個鉤子,若是有的話,就會先執行 npm run prelint,而後執行 npm run lint,最後執行 npm run postlint。

{
  "name": "myproject",
  "devDependencies": {
    "eslint": "latest"
    "karma": "latest"
  },
  "scripts": {
    "lint": "eslint --cache --ext .js --ext .jsx src",
    "test": "karma start --log-leve=error karma.config.js --single-run=true",
    "pretest": "npm run lint",
    "posttest": "echo 'Finished running tests'"
  }
}


複製代碼

上面代碼是一個 package.json 文件的例子。若是執行 npm test,會按下面的順序執行相應的命令。

pretest

test

posttest

若是執行過程出錯,就不會執行排在後面的腳本,即若是 prelint 腳本執行出錯,就不會接着執行 lint 和 postlint 腳本。

npm bin

npm bin 命令顯示相對於當前目錄的,Node 模塊的可執行腳本所在的目錄(即 .bin 目錄)。

# 項目根目錄下執行
$ npm bin
./node_modules/.bin
複製代碼

建立全局連接

npm 提供了一個有趣的命令 npm link,它的功能是在本地包和全局包之間建立符號連接。咱們說過使用全局模式安裝的包不能直接經過 require 使用。但經過 npm link 命令能夠打破這一限制。舉個例子,咱們已經經過 npm install -g express 安裝了 express,這時在工程的目錄下運行命令:

npm link express ./node_modules/express -> /user/local/lib/node_modules/express

複製代碼

咱們能夠在 node_modules 子目錄中發現一個指向安裝到全局的包的符號連接。經過這種方法,咱們就能夠把全局包當作本地包來使用了。

除了將全局的包連接到本地之外,使用 npm link 命令還能夠將本地的包連接到全局。使用方法是在包目錄(package.json 所在目錄)中運行 npm link 命令。若是咱們要開發一個包,利用這種方法能夠很是方便地在不一樣的工程間進行測試。

建立包

包是在模塊基礎上更深一步的抽象,Node.js 的包相似於 C/C++ 的函數庫或者 Java、.Net 的類庫。它將某個獨立的功能封裝起來,用於發佈、更新、依賴管理和版本控制。Node.js 根據 CommonJS 規範實現了包機制,開發了 npm 來解決包的發佈和獲取需求。 Node.js 的包是一個目錄,其中包含了一個 JSON 格式的包說明文件 package.json。嚴格符合 CommonJS 規範的包應該具有如下特徵:

。package.json 必須在包的頂層目錄下; 。二進制文件應該在 bin 目錄下; 。JavaScript 代碼應該在 lib 目錄下; 。文檔應該在 doc 目錄下; 。單元測試應該在 test 目錄下。

Node.js 對包的要求並無這麼嚴格,只要頂層目錄下有 package.json,並符合一些規範便可。固然爲了提升兼容性,咱們仍是建議你在製做包的時候,嚴格遵照 CommonJS 規範。

咱們也能夠把文件夾封裝爲一個模塊,即所謂的包。包一般是一些模塊的集合,在模塊的基礎上提供了更高層的抽象,至關於提供了一些固定接口的函數庫。經過定製 package.json,咱們能夠建立更復雜,更完善,更符合規範的包用於發佈。

Node.js 在調用某個包時,會首先檢查包中 packgage.json 文件的 main 字段,將其做爲包的接口模塊,若是 package.json 或 main 字段不存在,會嘗試尋找 index.js 或 index.node 做爲包的接口。

package.json 是 CommonJS 規定的用來描述包的文件,徹底符合規範的 package.json 文件應該含有如下字段:

name: 包的名字,必須是惟一的,由小寫英文字母、數字和下劃線組成,不能包含空格。

description: 包的簡要說明。

version: 符合語義化版本識別規範的版本字符串。

keywords: 關鍵字數組,一般用於搜索。

maintainers: 維護者數組,每一個元素要包含 name 、email(可選)、web(可選)字段。

contributors: 貢獻者數組,格式與 maintainers 相同。包的做者應該是貢獻者數組的第一個元素。

bugs: 提交 bug 的地址,能夠是網址或者電子郵件地址。

licenses: 許可證數組,每一個元素要包含

type(許可證的名稱)和 url(連接到許可證文本的地址)字段。

repositories: 倉庫託管地址數組,每一個元素要包含 type(倉庫的類型,如 git)、URL(倉庫的地址)和 path(相對於倉庫的路徑,可選)字段。

dependencies: 包的依賴,一個關聯數組,由包名稱和版本號組成。

包的發佈

經過使用 npm init 能夠根據交互式回答產生一個符合標準的 package.json。建立一個 index.js 做爲包的接口,一個簡單的包就製做完成了。 在發佈前,咱們還須要得到一個帳號用於從此維護本身的包,使用 npm adduser 根據提示完成帳號的建立。

完成後可使用 npm whoami 檢測是否已經取得了帳號。

接下來,在 package.json 所在目錄下運行 npm publish,稍等片刻就能夠完成發佈了,打開瀏覽器,訪問 search.npmjs.org/ 就能夠找到本身剛剛發佈的包了。如今咱們能夠在世界的任意一臺計算機上使用 npm install neveryumodule 命令來安裝它。

若是你的包未來有更新,只須要在 package.json 文件中修改 version 字段,而後從新使用 npm publish 命令就好了。 若是你對已發佈的包不滿意,可使用 npm unpublish 命令來取消發佈。

相關文章
相關標籤/搜索