Node入門教程(7)第五章:node 模塊化(下) npm與yarn詳解

Node的包管理器

JavaScript缺乏包結構的定義,而CommonJS定義了一系列的規範。而NPM的出現則是爲了在CommonJS規範的基礎上,實現解決包的安裝卸載,依賴管理,版本管理等問題。css

CommonJS是一個致力於構建統一的JS生態系統,它能夠兼容web服務器、桌面應用、命令行應用、瀏覽器等。它定義了各類開發的規範和API不只僅模塊化相關的規範)
官網的說明: a group with a goal of building up the JavaScript ecosystem for web servers, desktop and command line apps and in the browser.html

CommonJS的模塊主要以下:前端

  • binary: Binary Data Objects (byte arrays and/or strings) (proposals, discussion, early implementations)
  • encodings: Encodings and character sets (proposals, discussion, early implementations)
  • io: I/O Streams (proposals, discussion)
  • fs, fs-base: Filesystem (proposals, discussion, early implementations)
  • system: System Interface (stdin, stdout, stderr, &c) (1.0, amendments proposed)
  • assert, test: Unit Testing (1.0, amendment proposals pending)
  • sockets: Socket I/O TCP/IP sockets (early proposals)
  • event-queue: Reactor Reactor/Event Queue (early proposals)
  • worker: Worker Worker (concurrent shared nothing process/thread) (proposal)
  • console: console (proposal)

包結構

一個符合CommonJS規範的包應該是以下這種結構:vue

  • 一個package.json文件應該存在於包頂級目錄下
  • 二進制文件應該包含在bin目錄下。
  • JavaScript代碼應該包含在lib目錄下。
  • 文檔應該在doc目錄下。
  • 單元測試應該在test目錄下。

package.json 說明

package.json文件就是當前項目或者包(js模塊、組件)的配置文件,全部當前項目的依賴的第三方模塊,當前項目的配置等都定義在package.json文件中,當前它有必定的規範,咱們能夠經過npm命令初始化和建立package.json文件。node

建立package.json文件步驟:react

# 打開命令行,確保您已經安裝好了node mkdir demos cd demos # 初始化當前項目的package.json文件,-y表示默認參數。 npm init -y  ######當前demos目錄下就會增長一個package.json文件,內容以下:###### { "name": "demos", // 項目名稱 "version": "1.0.0", // 項目的版本號 "description": "", // 項目描述 "main": "index.js", // 引用目錄模塊的入口文件 "scripts": { // 能夠經過npm運行的shell命令腳本 "test": "echo \"Error: no test specified\" && exit 1" // 能夠經過npm run test 啓動 }, "keywords": [], // 項目的關鍵詞 "author": "", // 做者,通常能夠寫上郵箱 "license": "ISC" // 當前項目或者包的開源協議 } 

package.json文件說明:webpack

  • name。包名,須要在NPM上是惟一的。不能帶有空格。git

  • description。包簡介。一般會顯示在一些列表中。github

  • version。版本號。一個語義化的版本號(http://semver.org/ ),一般爲x.y.z。web

    • x(Major): 主版本號:當你作了不兼容的 API 修改,通常一個比較完整大改版,須要修改x(通常增長1)
    • y(Minor): 次版本號:當你作了向下兼容的功能性新增
    • z(Patch): 修訂號:當你作了向下兼容的問題修正。
    • 其餘參考中文翻譯
  • keywords。關鍵字數組。用於NPM中的分類搜索。

  • maintainers。包維護者的數組。數組元素是一個包含name、email、web三個屬性的JSON對象。

  • contributors。包貢獻者的數組。第一個就是包的做者本人。在開源社區,若是提交的patch被merge進master分支的話,就應當加上這個貢獻patch的人。格式包含name和email。如:

    "contributors": [{ "name": "Jackson Tian", "email": "mail @gmail.com" }, { "name": "fengmk2", "email": "mail2@gmail.com" }], 
  • bugs。一個能夠提交bug的URL地址。能夠是郵件地址(mailto:mailxx@domain),也能夠是網頁地址(http://url)。

  • licenses。包所使用的許可證。

  • repositories。託管源代碼的地址數組。

  • dependencies。當前包須要的依賴。這個屬性十分重要,NPM會經過這個屬性,幫你自動加載依賴的包。

參考一個express框架的的包配置文件:

// 如下包,並非完整的,我截取了部份內容。 { "name": "express", "description": "Fast, unopinionated, minimalist web framework", "version": "4.16.3", "author": "TJ Holowaychuk <tj@vision-media.ca>", "contributors": [ "Aaron Heckmann <aaron.heckmann+github@gmail.com>", "Ciaran Jessup <ciaranj@gmail.com>", ], "license": "MIT", "repository": "expressjs/express", "homepage": "http://expressjs.com/", "keywords": [ "express", "framework", ], "dependencies": { "accepts": "~1.3.5", "array-flatten": "1.1.1", "statuses": "~1.4.0", "type-is": "~1.6.16", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "devDependencies": { "after": "0.8.2", "cookie-parser": "~1.4.3", "cookie-session": "1.3.2", "ejs": "2.5.7", "connect-redis": "~2.4.1", "vhost": "~3.0.2" }, "engines": { "node": ">= 0.10.0" }, "files": [ "LICENSE", "History.md", "Readme.md", "index.js", "lib/" ], "scripts": { "lint": "eslint .", "test": "mocha --require test/support/env --reporter spec --bail --check-leaks --no-exit test/ test/acceptance/", } } 

npm進行包管理

npm(node package manager)原本是Node.js的包管理工具,但隨着JS這幾年的蓬勃發展, npm已經再也不侷限於node平臺,尤爲是Webpack的普遍應用,前端包管理基本由npm統一管理了。

npm相關學習資源:

npm安裝本地包

安裝第三方包到本地,只須要打開命令行,經過cd命令進入咱們項目的根目錄(確保您以前已經初始化了package.json文件)。
而後執行npm的install命令,以下:

語法:npm install <package> --save-prod

$ cd demos $ npm install lodash --save-prod # 輸出以下: npm notice created a lockfile as package-lock.json. You should commit this file. + lodash@4.17.5 # 有個+號,表明安裝當前。 added 1 package in 1.091s # 這裏告訴咱們天津一個包用了1.091秒 

解釋:

  • install: 表明安裝第三方包的意思,能夠直接用 i代替。
  • --save-prod: 表明把當前安裝包的配置寫入到當前package.json文件中, 能夠用 -P代替。

咱們項目文件夾會有兩個變化:第一個就是增長了package.json文件和node_modeules文件夾

如下是package.json的增長的內容

{
  "name": "demos", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", + "dependencies": { // 增長 + "lodash": "^4.17.5" // 增長lodash的安裝包 + } // 增長 } 

node_modeules文件夾存放咱們剛剛安裝包的文件。

命令簡寫的形式:

$ npm install lodash --save-prod $ npm i lodash -P ################################################## ## 老版本中 --save 或者 -S,如今還支持,但建議用-P代替## ################################################## $ npm i lodash -S $ npm install lodash --save 

安裝開發階段依賴的本地包

有時候咱們須要一些第三方的包,僅僅在開發階段依賴,則須要把npm的install命令添加--save-dev參數。

例如,咱們開發階段須要用gulp進行打包,則須要安裝gulp包。

$ npm install gulp --save-dev # 如下是簡寫形式, -D === --save-dev $ npm i gulp -D 

開發依賴,會在package.json文件的devDependencies下添加安裝包的配置。以下所示:

{
  "name": "demos", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "lodash": "^4.17.5" }, + "devDependencies": { + "gulp": "^3.9.1" + } } 

自動根據配置package.json文件下載安裝依賴的包

package.json文件能夠幫咱們進行包的管理和配置,若是在項目根目錄下直接運行npm install,npm會自動的根據package.json文件中的dependenciesdevDependencies中配置的第三方包進行安裝。這尤爲是在團隊開發和項目部署時很是有用。

只須要: npm i

package.json文件中對模塊的依賴可使用~、^、*來控制。

  • ~: 安裝兼容模塊新發布的補丁版本,也就是說主版本號和次版本號不能變,最後一位修改號(補丁)可變化。例如:~1.1.0
  • ^: (默認)主版本號不能變,後面兩個版本可變,兼容模塊新發布的次版本、補丁版本:^1.1.0
  • *: 兼容模塊新發布的大版本、小版本、補丁版本:任何版本均可以。

設置國內鏡像

npm安裝的包的時候,先檢查本地是否有緩存,若是最近剛安裝過,並且本地有緩存的話,直接用緩存。若是沒有緩存會到npm的在線倉庫下載並安裝。默認的倉庫地址:https://registry.npmjs.org/.

可是因爲服務器在國外,並且國內你懂得,有時候下載比較大點的第三方包會很是慢,並且常常斷掉。建議使用國內比較穩定快速的鏡像,好比淘寶的npm鏡像。

設置npm下載包的鏡像爲淘寶的鏡像,設置方式:

打開終端(windows下請使用powershell)

# 設置淘寶鏡像 $ npm config set registry https://registry.npm.taobao.org  # 驗證是否配置成功 $ npm config get registry # 輸出以下則表示成功: https://registry.npm.taobao.org/ 

另一種辦法:用cnpm替代npm。

# 首先安裝cnpm: $ npm install -g cnpm --registry=https://registry.npm.taobao.org  # 使用 $ cnpm install expresstall express 

控制安裝的版本號

咱們經過npm安裝第三方包的時候,能夠指定安裝的具體版本,在包的後面添加一個@符號和具體版本號就能夠了。

# 安裝0.1.1版本的sax $ npm install sax@0.1.1 # 安裝最新的sax $ npm install sax@latest  # 還能夠指定範圍 $ npm install sax@">=0.1.0 <0.2.0" 

安裝全局依賴的包

有些包不只僅須要咱們本地開發運行時依賴,有時候也須要咱們在命令行的任意位子啓動和使用第三方包,那麼就須要進行全局安裝。
語法: npm install -g <package>
好比,gulp咱們有時候在任何一點地方均可能用到gulp命令工具,則須要全局安裝gulp。

$ npm install gulp --global # 簡寫 $ npm i -g gulp  # 安裝成功後,咱們就能夠隨時隨地均可以運行gulp命令了 $ gulp -v 

更新安裝包

更新本地的安裝包:在 package.json 文件所在的目錄中執行 npm update 命令。
更新全局的安裝包:

$ npm update -g jshint 

卸載安裝包

卸載本地安裝包

$ npm uninstall --save-prod lodash # 簡寫 $ npm un -P lodash 

卸載全局安裝包

$ npm uninstall -g lodash 

其餘npm經常使用命令

更新升級npm

$ npm i npm 

羅列出當前安裝的全部的包

$ npm list  # 控制列出全部包的目錄層級 --depth 控制層級 $ npm list --depth=0  # 能夠用ls 替代 list $ npm ls --depth=1  # 羅列全局的安裝的包 $ npm -g list --depth=0  # 如下是個人安裝的包 /usr/local/lib ├── autoprefixer@7.2.3 ├── babel-cli@6.18.0 ├── bower@1.8.2 ├── create-react-app@1.0.2 ├── egg-init@1.9.0 ├── eslint@3.12.2 ├── generator-keystone@0.5.1 ├── grunt-cli@1.2.0 ├── gulp@3.9.1 ├── json-server@0.12.1 ├── live-server@1.2.0 ├── n@2.1.5 ├── nodemon@1.11.0 ├── npm@5.6.0 ├── npm-check@5.4.0 ├── npm-check-updates@2.8.8 ├── parcel-bundler@1.4.1 ├── sails@0.12.13 ├── static-server@2.0.5 ├── typescript@2.2.1 ├── vue-cli@2.9.3 ├── vue-migration-helper@1.1.1 ├── UNMET PEER DEPENDENCY webpack@>=1.3.0 <3 ├── webpack-dev-server@1.16.2 └── yo@1.8.5 

npm後續

  • 發佈npm包

npm不只僅能夠幫助咱們進行安裝第三包,咱們也能夠本身發佈一個包,供全世界的開發人員使用。
這塊內容能夠,查看官網的npm publish部分。

  • npm scripts 使用

咱們能夠經過npm編寫一些使用頻率很是高的:打包、運行測試、運行部署等shell命令到package.json文件的 scripts配置節點,方便咱們執行一些複雜的重複性很高的任務。
具體學習:請移步阮一峯老師的教程

如下只是簡單介紹一下原理和使用:

npm 腳本的原理很是簡單。每當執行npm run,就會自動新建一個 Shell,在這個 Shell 裏面執行指定的腳本命令。所以,只要是 Shell(通常是 Bash)能夠運行的命令,就能夠寫在 npm 腳本里面。

好比:

// package.json文件 { // ... "scripts": { "dev": "gulp dev" // 經過npm run dev 能夠直接在shell中執行gulp dev命令。 } } 

在scripts中定義的腳本,咱們能夠直接經過npm run <keyname>運行,跟在shell中運行同樣。

常見的通常使用技巧:

// package.json文件
{
  // ...
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
    "test": "npm run unit",
    "lint": "eslint --ext .js,.vue src test/unit",
    "build": "node build/build.js"
  }
}
 # 如下是執行對應的任務 npm run build # 運行打包任務 npm run dist # 運行生成dist目錄文件的命令 npm run dev # 運行開發調試 npm run test # 運行測試  # 如下有幾個內置的能夠簡寫: npm start # => npm run start npm stop # => npm run stop的簡寫 npm test # => npm run test的簡寫 

yarn 是npm以外的另外一種選擇

yarn是Facebook出的一款替代npm的包管理工具,npm的功能它都有對應,並且使用方法也都很類似。那爲何Facebook再造一個重複的輪子呢?

在yarn以前的npm版本的問題:(固然部分問題已經修復)

  • npm 安裝包(packages)的速度不夠快,是順序下載,不是並行。
  • 拉取的 packages 可能版本不一樣(最新的版本已經能夠把版本鎖住:package-lock.json)
  • npm 容許在安裝 packages 時執行代碼,這就埋下了安全隱患

yarn能兼容npm的配置文件package.json,使用方式也很是接近npm,因此咱們能夠基本上無縫從npm遷移到yarn。並且yarn的確的確夠快、夠穩定、夠優秀。yarn的優勢:

  • 速度快:Yarn 緩存了每一個下載過的包,因此再次使用時無需重複下載。 同時利用並行下載以最大化資源利用率,所以安裝速度更快。並行下載安裝包,速度真的是槓槓的。
  • 比較安全:在執行代碼以前,Yarn 會經過算法校驗每一個安裝包的完整性。
  • 可靠:使用詳細、簡潔的鎖文件格式和明確的安裝算法,Yarn 可以保證在不一樣系統上無差別的工做。
  • 無論安裝順序如何,相同的依賴關係將在每臺機器上以相同的方式安裝。
  • 將依賴包的不一樣版本歸結爲單個版本,以免建立多個副本。
  • 重試機制確保單個請求失敗並不會致使整個安裝失敗。

yarn的安裝

mac下安裝:

brew install yarn

windows安裝:直接下載安裝包

測試是否安裝成功:

yarn --version
# 如下輸出的是yarn的版本號,筆者的是以下,你的可能跟我不同。 0.24.5 

npm和yarn的cli差別

如下只是簡單介紹一下yarn的使用方法:

初始化一個新的項目

yarn init
# 對應npm npm init 

添加一個依賴包

yarn add [package]
yarn add [package]@[version]
yarn add [package]@[tag]
# 對應npm npm install [package] 

更新一個依賴包

yarn upgrade [package]
yarn upgrade [package]@[version]
yarn upgrade [package]@[tag]
 # 對應npm npm update [package] 

刪除一個依賴包

yarn remove [package]
# 對應npm npm uninstall [package] 

安裝全部的依賴包

yarn
or
yarn install
 # 對應npm npm install 

全局安裝依賴包

yarn global add [package]
npm i [package] -g

yarn global remove [package]
npm un [package] -g

yarn upgrade [package]
npm update [package]

注意:yarn全局安裝了一些命令包以後,可能全局範圍內不能訪問,這時候須要把yarn的全局的bin目錄加入到操做系統的環境變量中。

# 查看yarn的全局bin目錄 yarn global bin  # 輸出(mac下) /usr/local/Cellar/node/9.9.0/bin 

總結

至此,咱們已經基本掌握了nodejs的包管理、包加載機制等基本原理,後面就是咱們怎麼應用他們進行開發了。


參考:

深刻淺出Node.js(三):深刻Node.js的模塊機制

Yarn 中文網

阮一峯老師的教程


老馬免費視頻教程

返回教程列表首頁

github地址:https://github.com/malun666/aicoder_node

相關文章
相關標籤/搜索