官方說明:https://classic.yarnpkg.com/zh-Hans/docs/package-json
原文地址:yarn命令的使用
name 和 version 是 package.json 文件里最重要的兩個字段,沒有它們你的包無法被安裝。 name 和 version 字段一起用來創建一個唯一 id。
yarn add [name]
這是你的包的名字。它在 URL 中、作為命令行參數、作為 node_modules 里的目錄名使用。
node_modules/[name] https://registry.npmjs.org/[name]/-/[name]-[version].tgz
添加一個依賴
通過
yarn add添加依賴會更新package.json以及yarn.lock文件
yarn add <packageName>依賴會記錄在package.json的dependencies
yarn global add <packageName>全局安裝依賴
更新一個依賴
yarn upgrade用於更新包到基於規范范圍的最新版本
yarn upgrade --latest # 忽略版本規則,升級到最新版本,並且更新 package.json
移除一個依賴
yarn remove <packageName>
安裝 package.json 中的所有文件
yarn或者yarn install
運行腳本
yarn run用來執行在package.json中scripts屬性下定義的腳本
// package.json { "scripts": { "dev": "node app.js", "start": "node app.js" } }
yarn run dev # yarn 執行 dev 對應的腳本 node app.js npm run # npm yarn start # yarn npm start # npm
與 npm 一樣 可以有
yarn start和yarn test兩個簡寫的運行腳本方式
顯示某個包信息
列出項目的所有依賴
yarn list# 列出當前項目的依賴
yarn global list # 列出全局安裝的模塊
原文地址:
理一理 npm, yarn, package.json, pakage-lock.json, yarn.lock 之間的關系
package-lock.json和yarn.lock的包依賴區別
npm的全稱是 Node Package Manager,簡單來說它就是一個包 (package) 管理工具。
npm的公司買了一個倉庫用來存放這些我們日常所用的包,我們只需要安裝
npm,就能很輕易的通過
npm來很方便的安裝這些包了。
node包管理
包是一段可以復用的代碼,這段代碼可以從全局注冊表下載到開發者的本地環境。每個包可能會,也可能不會依賴於別的包。簡單地說,包管理器是一段代碼,它可以讓你管理依賴(你或者他人寫的外部代碼),你的項目需要這些依賴來正確運行。
npm簡化了我們安裝各類包的過程,而
package.json的作用就是記錄我們用
npm安裝過哪些包的。
package.json可以通過初始化語句
npm init來生成,剛生成的
package.json的
"dependencies"里面是空的,隨着你逐漸通過
npm安裝各類包,安裝過哪些包,版本號是什么,都會記錄在
"dependencies"里面
package.json一起交給別人,他就能知道要運行這個目需要安裝哪些包了。更方便的是,他只要在自己的電腦上輸入
npm install,
npm就會自動安所有這些需要的包。
為啥我們需要一個包管理工具呢?因為我們在Node.js上開發時,會用到很多別人寫的JavaScript代碼。如果我們要使用別人寫的某個包,每次都根據名稱搜索一下官方網站,下載代碼,解壓,再使用,非常繁瑣。
更重要的是,如果我們要使用模塊A,而模塊A又依賴於模塊B,模塊B又依賴於模塊C和模塊D,npm可以根據依賴關系,把所有依賴的包都下載下來並管理起來。否則,靠我們自己手動管理,肯定既麻煩又容易出錯。
於是一個集中管理的工具應運而生:
- 大家都把自己開發的模塊打包后放到
npm官網上,如果要使用,直接通過npm安裝就可以直接用,不用管代碼存在哪,應該從哪下載。 Yarn是為了彌補npm的一些缺陷[速度慢,穩定性高]而出現的。”
npm
npm為你和你的團隊打開了連接整個JavaScript天才世界的一扇大門。它是世界上最大的軟件注冊表,每星期大約有 30 億次的下載量,包含超過 600000 個 包(package) (即,代碼模塊)。來自各大洲的開源軟件開發者使用npm互相分享和借鑒。包的結構使您能夠輕松跟蹤依賴項和版本。
下面是關於 npm 的快速介紹:npm 由三個獨立的部分組成:
- 網站
網站 是開發者查找包(package)、設置參數以及管理npm使用體驗的主要途徑。 - 注冊表(
registry)
注冊表 是一個巨大的數據庫,保存了每個包(package)的信息。 - 命令行工具 (
CLI)CLI通過命令行或終端運行。開發者通過 CLI 與 npm 打交道。
yarn
Yarn發布於2016年10月,並在Github上迅速擁有了2.4萬個Star。而npm只有1.2萬個star。這個項目由一些高級開發人員維護,包括了Sebastian McKenzie(Babel.js)和Yehuda Katz(Ember.js、Rust、Bundler等)。
Yarn一開始的主要目標是解決上一節中描述的由於語義版本控制而導致的npm安裝的不確定性問題。雖然可以使用npm shrinkwrap來實現可預測的依賴關系樹,但它並不是默認選項,而是取決於所有的開發人員知道並且啟用這個選項。
Yarn采取了不同的做法。每個yarn安裝都會生成一個類似於npm-shrinkwrap.json的yarn.lock文件,而且它是默認創建的。除了常規信息之外,yarn.lock文件還包含要安裝的內容的校驗和,以確保使用的庫的版本相同。
yarn的優化主要體現在:
-
速度快 :
- 並行安裝:無論 npm 還是 Yarn 在執行包的安裝時,都會執行一系列任務。npm 是按照隊列執行每個 package,也就是說必須要等到當前 package 安裝完成之后,才能繼續后面的安裝。而 Yarn 是同步執行所有任務,提高了性能。
- 離線模式:如果之前已經安裝過一個軟件包,用Yarn再次安裝時之間從緩存中獲取,就不用像npm那樣再從網絡下載了。
- 安裝版本統一:為了防止拉取到不同的版本,
Yarn有一個鎖定文件 (lock file) 記錄了被確切安裝上的模塊的版本號。每次只要新增了一個模塊,Yarn 就會創建(或更新)yarn.lock這個文件。這么做就保證了,每一次拉取同一個項目依賴時,使用的都是一樣的模塊版本。 - 更好的語義化:
yarn改變了一些npm命令的名稱,比如yarn add/remove,感覺上比 npm 原本的install/uninstall要更清晰。
node包的安裝
-
執行工程自身
preinstall- 當前 npm 工程如果定義了
preinstall鈎子此時會被執行。
- 當前 npm 工程如果定義了
-
確定首層依賴
- 模塊首先需要做的是確定工程中的首層依賴,也就是
dependencies和devDependencies屬性中直接指定的模塊(假設此時沒有添加npm install參數)。工程本身是整棵依賴樹的根節點,每個首層依賴模塊都是根節點下面的一棵子樹,npm 會開啟多進程從每個首層依賴模塊開始逐步尋找更深層級的節點。
- 模塊首先需要做的是確定工程中的首層依賴,也就是
-
獲取模塊
- 獲取模塊是一個遞歸的過程,分為以下幾步:
- 獲取模塊信息。在下載一個模塊之前,首先要確定其版本,這是因為
package.json中往往是semantic version(semver,語義化版本)。此時如果版本描述文件(npm-shrinkwrap.json或package-lock.json)中有該模塊信息直接拿即可,如果沒有則從倉庫獲取。如packaeg.json中某個包的版本是^1.1.0,npm就會去倉庫中獲取符合1.x.x形式的最新版本。 - 獲取模塊實體。上一步會獲取到模塊的壓縮包地址(
resolved字段),npm 會用此地址檢查本地緩存,緩存中有就直接拿,如果沒有則從倉庫下載。 - 查找該模塊依賴,如果有依賴則回到第1步,如果沒有則停止。
-
模塊扁平化(
dedupe)- 上一步獲取到的是一棵完整的依賴樹,其中可能包含大量重復模塊。比如 A 模塊依賴於
loadsh,B 模塊同樣依賴於lodash。在 npm3 以前會嚴格按照依賴樹的結構進行安裝,因此會造成模塊冗余。yarn和從npm5開始默認加入了一個dedupe的過程。它會遍歷所有節點,逐個將模塊放在根節點下面,也就是node-modules的第一層。當發現有重復模塊時,則將其丟棄。這里需要對重復模塊進行一個定義,它指的是模塊名相同且semver兼容。每個semver都對應一段版本允許范圍,如果兩個模塊的版本允許范圍存在交集,那么就可以得到一個兼容版本,而不必版本號完全一致,這可以使更多冗余模塊在dedupe過程中被去掉。
- 上一步獲取到的是一棵完整的依賴樹,其中可能包含大量重復模塊。比如 A 模塊依賴於
-
安裝模塊
- 這一步將會更新工程中的
node_modules,並執行模塊中的生命周期函數(按照preinstall、install、postinstall的順序)。
- 這一步將會更新工程中的
-
執行工程自身生命周期
- 當前 npm 工程如果定義了鈎子此時會被執行(按照
install、postinstall、prepublish、prepare的順序)。
- 當前 npm 工程如果定義了鈎子此時會被執行(按照
Pakage-lock.json文件的作用
在5.X.X之后的npm版本中,pakage-lock.json是會被自動生成的。pakage-lock.json被創建的目的就是更精確的記錄包的各類信息。
version記錄了包的版本,resolved記錄了包的下載來源。這樣,在通過npm install命令安裝時,不僅能夠安裝相同版本號的包,而且連包的下載源都是一樣的,這樣,我們就實現了真正意義上的安裝一模一樣的依賴包,從而確保程序的成功運行。
那么我們在有了pakage-lock.json后是不是就不需要package.json了呢?不,我們依舊需要package.json。這兩個文件之間的關系可以這樣來理解:package.json負責的不僅僅是記錄各種依賴包,它還記錄了其他信息,包括project properties, description, author & license 等等,而pakage-lock.json的作用僅僅是輔助package.json鎖定依賴包的版本。pakage-lock.json可有可無,沒有的話只是不能鎖定版本而已,而package.json是必須要有的。
lock文件
鎖文件是由包管理器自動生成的。它包含了重現全部的依賴源碼樹需要的所有信息、你的項目依賴中的所有信息,以及它們各自的版本。
現在值得強調的是,Yarn 使用了鎖文件,而 npm5以前沒有默認鎖文件,npm5之后加入了默認鎖文件功能。我們會談到這種差別導致的一些后果。既然我已經向你介紹了包管理器這部分,現在我們來討論依賴本身。
目前常見的兩種lock文件:
packahe-lock.json是npm5之后默認生成的鎖文件yarn.lock是yarn的鎖文件
yarn.lock解析
顯然yarn.lock鎖文件把所有的依賴包都扁平化的展示了出來,對於同名包但是semver不兼容的作為不同的字段放在了yarn.lock的同一級結構中。
yarn.lock文件
yarn.lock 鎖定了安裝包的精確版本以及所有依賴項。有了這個文件,你可以確定項目團隊的每個成員都安裝了精確的軟件包版本,部署可以輕松地重現,且沒有意外的 bug,並且這個文件可以使得程序在不同的機器上可以攻取一致的體驗
Yarn 鎖定文件的和安裝算法的存在,確保了將應用程序部署到生產環境時,安裝的依賴在開發機器之間,產生的文件和文件夾結構完全相同。
