Yarn在前端開發者中必然不陌生,目前來說大部分使用的都是Yarn 1.x的版本,其實Yarn 1.x很多時候定位有些尴尬,在設計上還是從npm上借鑒了很多,甚至在大多開發者眼中隻是将
package-lock.json
換成了
yarn.lock
而已(
yarn workspaces
是較大的不同),雖然号稱在速度上有優勢,但npm所具有的缺點Yarn 1.x還是不可避免地會存在。
是以促使了Yarn 2地出現,在盡可能保留1.x的使用方式和功能的同時,還提出和實作/重構了很多新的功能,目前1.x已經不再進行版本更新了,并且1.x的文檔也已經轉移到https://classic.yarnpkg.com/。本文不會詳細介紹Yarn 2引入了哪些新的功能,僅從安裝、使用以及現在的開發模式的角度了解Yarn 2,具體新功能可以到Changelog或Features中檢視。
安裝Yarn 2
在維護多個項目時經常遇到npm版本不統一的情況,是以我們經常需要在同一台機器上安裝多個
Node.js
,是以nvm和nvm-windows出現了,但作為開發者仍要記得在不同項目間切換版本。而Yarn 2認為自己本身就應該是項目的依賴,甚至版本也應該被鎖定(當然可以更新),是以Yarn 2會将自己維護到項目中,目前仍需要借助
yarn 1
完成安裝:
npm install -g yarn # 全局安裝yarn 1
yarn --version # A
雖然看起來有些怪異,但也能了解,畢竟一個如此普及的工具不可能不考慮相容性和遷移難度就進行完全的覆寫,Yarn 2的出現也要保證原有Yarn 1的正常使用。
工程中更新為Yarn 2
前面說到Yarn 2是把自己作為項目的一個普通依賴看待的,是以更新Yarn 2也是針對項目而言的:
cd /path/to/project
# 上面A行得到的版本如果是1.22+
yarn set version berry # B1
# 上面A行得到的版本如果低于1.22
yarn policies set-version berry # B2
執行完B1或B2行之後,工程根目錄下會新增一個
.yarn
目錄及一個
.yarnrc.yml
的配置檔案:
-
目錄:存放Yarn 2的具體執行檔案、由Yarn 2安裝的依賴等.yarn
-
配置檔案:此工程針對Yarn 2的具體配置檔案,和.yarnrc.yml
、.npmrc
功能類似,這裡要注意Yarn 2不會再讀取.yarnrc
、.npmrc
中的配置,同時檔案擴充也必須是yml,.yarnrc
不能生效.yarnrc
# .yarn目錄初始結構
.yarn
├── releases
│ └── yarn-berry.js
# .yarnrc.yml初始結構
yarnPath: ".yarn/releases/yarn-berry.js"
和
.yarn
都應該送出到倉庫。
.yarnrc.yml
更新Yarn 2版本
由于Yarn 2目前仍在快速疊代中,為了修複問題或者想要體驗新功能時,更新Yarn 2的版本也是個正常操作,所幸更新Yarn 2版本也很容易,而且提供了多種方式:
# 更新至最新的釋出版本 - 大衆
yarn set version latest
# 從master分支更新版本 - 嘗鮮
yarn set version from sources
# 從其他分支更新版本 - 需要解決特定需求
yarn set version from sources --branch 1211
上面是從Yarn 2倉庫中直接更新到你的工程中,更新完成後一般需要通過
yarn
或
yarn install
更新依賴。
按照上面的步驟安裝/更新Yarn 2後,在目前工程下應該就能夠正常運作Yarn 2了,可以通過
yarn --version
來确認目前是否是2.x版本。
使用Yarn 2管理依賴
Yarn 2一些常見的使用方式和Yarn 1沒什麼差別,比如:
# 安裝依賴
yarn
yarn install
# 添加依賴
yarn add [package] [--dev|--peer]
# 删除依賴
yarn remove [package]
當然也有新增/替換的一些指令:如
yarn up
用于更新依賴(Yarn 1.x中的
yarn upgrade
)、
yarn dlx
用于臨時執行依賴(和
npx
類似),具體可檢視CLI文檔。
這裡我們重點關注一下依賴的安裝,如果我們現在在工程中進行依賴安裝可能會傻眼:
- 多了個
的檔案.pnp.js
-
目錄下多了很多檔案.yarn
-
目錄被清空了node_modules
- 工程可能也跑不起來了
.pnp.js
和 .yarn
目錄新增檔案意義
.pnp.js
.yarn
這就不得不提到Yarn 2的預設使用的是
pnp
的方式安裝依賴,和傳統的
node_modules
方式管理依賴相比最重要的不同是所有依賴是以zip包的方式存在,預設存放在
.yarn/cache
目錄下。而以zip包的方式管理依賴就會有個緻命的問題:我們的代碼識别不了,更别提找到對應的依賴檔案了,是以Yarn 2為我們生成了
.pnp.js
檔案解決這個問題。至于采用這種方式的優點這裡簡單列舉一下,有興趣的可以看下官方解釋,
Yarn 2認為工程依賴的鎖定不僅僅隻依靠
yarn.lock
達到,而應該将依賴也送出到倉庫,是以
.yarn
目錄都應該被送出到倉庫。而這在傳統的
node_modules
方式下是不可行的,不僅是因為更新後産生的變更數量,更因為一個稍微大些的工程
node_moduels
的檔案數量和體積都很容易達到Git無法處理的地步。而因為Yarn 2使用zip包的方式管理依賴,大大減少了檔案數量和檔案體積,故而使得工程的依賴能夠進行版本管理,進而能夠完美地實作依賴鎖定。
在目前的工程協作開發中,協作者拉取代碼後,第一步就要進行依賴的安裝工作,但Yarn 2改變了這個境況,既然工程依賴都被送出到倉庫中了,協作者拉取代碼後甚至都不再需要執行依賴安裝的步驟,因為依賴已經在那裡了,這就是Yarn 2提出的零安裝zero-install。這也順帶解決了諸如伺服器網絡限制不能下載下傳依賴、新分支更新依賴老分支不能正常運作等問題。
工程跑不起來的解決方案
那是不是有了
.pnp.js
我們的工程就能完全正常了呢?很遺憾也沒這麼簡單:目前很多工具還沒有實作
Plug'n'Play
規範,是以目前很可能你的工程目前仍然跑不起來,那是不是就意味着我們不能用Yarn 2了呢?當然不是,Yarn 2提供了兩種安裝依賴的方式:
pnp
(預設)和
node-modules
(沒有寫錯,不是node_modules),配置方式:
# .yarnrc.yml
yarnPath: ".yarn/releases/yarn-berry.js"
# 如果工程跑不起來可以先嘗試增加下面的配置:
nodeLinker: "pnp"
pnpMode: "loose"
# 如果仍然跑不起來,可以用下面的配置完全按照以前的依賴按照方式
nodeLinker: "node-modules"
如果是"pnp"的話(預設情況),
nodeLinker
預設為"strict",這種情況下所有用到的依賴都必須顯式地聲明在
pnpMode
中,也就是說如果你的子產品聲明了webpack作為依賴,webpack中聲明了acorn作為依賴,在"strict"模式下你的子產品不能直接引入acron,否則會報錯。而"loose"模式下是允許的,但卻不是推薦用法。
package.json
設定為"node-modules"就和Yarn 1和npm的方式安裝依賴沒什麼差別了,所有依賴仍然存在于
nodeLinker
目錄下,這些情況下也不會生成
node_moduels
檔案,因為不需要從zip包中解析依賴了。
.pnp.js
有部分有名的前端工具支援了,具體可檢視支援清單,随着時間推移相信會有越來越多地支援。
Yarn 2配置
Yarn 2配置可以通過
yarn config
CLI完成,也可以通過直接編輯
.yarnrc.yml
檔案完成,有些配置和Yarn 1.x的配置差異挺大,全部的配置可查閱官方配置文檔,這裡以私有域的配置做一下示例:
# 使用yarn config
yarn config set --json npmScopes '{"lwz": {"npmRegistryServer": "http://npm.lwz.com"}}'
yarn config set --json unsafeHttpWhitelist '["*.lwz.com", "lwz.com"]'
使用 --json
允許複雜的配置,否則隻能配置string、number和boolean類型的配置項
當私有域名不是https時,需要增加 unsafeHttpWhitelist
配置添加私有域名,可以使用通配符
對應在
.yarnrc.yml
中:
# .yarnrc.yml
npmScopes:
lwz:
npmRegistryServer: "http://npm.lwz.com"
unsafeHttpWhitelist:
- "*.lwz.com"
- "lwz.com"
複雜的配置推薦在中直接編輯,使用
.yarnrc.yml
設定已存在的配置是一個覆寫的過程,是以如果想要保留之前的配置,還需要在配置時将之前的配置帶上。
yarn config set
總結
本文僅站在使用者的角度說明如何使用Yarn 2,對其新特性、優勢等方面并未深入講解,這些方面留待日後講解,如果想要深入了解可到官方文檔查閱。
- CHANGELOG
- Features
- 配置