原創專欄
居玉皓
于2015年加入去哪兒網,目前在平臺事業部前端架構組,主要從事前端基礎框架和工具的開發。熱愛開源社區,積極參與開發和維護活躍的開源項目,喜歡鉆研新技術和分享自己的見解。
在目前 Java 開發領域中,比較知名的模塊管理器有 npm、bower、 component,以及一周前由 Facebook 公司推出的 Yarn。盡管在眼下 2016 年,npm 逐漸有一種被 Java 開發社區欽定的趨勢,卻還遠未達到盡善盡美的地步。本文將會介紹使用 npm 管理模塊時可能會遇到的問題,以及探討剛剛出現在我們視野中的 Yarn 能帶來哪些改變,是否能幫助我們更好地管理 Java 模塊。
1. left-pad 事件
相信很多人還記得今年 3 月份在 Java 圈鬧得沸沸揚揚的 left-pad 事件。一個名為 Azer Ko?ulu 的程序員因為對 npm 公司不滿,將他發布在 npm 上的所有模塊進行了 unpublish 操作。其中就包括一個叫 left-pad 的模塊,它為很多知名的模塊如 React、Babel、Ember 所依賴。當 left-pad 被移除后,這些模塊均無法正常工作。從而導致了使用了它們的無以計數的項目也因此構建失敗。
事件之后,Babel 等模塊進行了緊急修復,將對它的依賴移除。又過了幾天,npm 公司公開道歉,并改變了他們的 unpublish 策略。所有模塊在發布 24 小時之后不再允許 unpublish,移除只能通過 npm 官方,同時要保證所要移除的模塊沒有被別人所依賴,以防止類似 left-pad 的事件再次發生。
2. npm install 可靠嗎
npm 公司這次對于 unpublish 策略的修改,避免了在構建時依賴模塊的丟失,然而這次暴露出來的問題卻使人們開始質疑 npm install 這一構建過程的可靠性。其中仍然存在一個不可忽視的問題,就是模塊內引用的其它模塊仍然不可控。
譬如說現在某個項目依賴了模塊 A, 我們當然可以為它指定一個唯一的版本。然而 A 所依賴的其它模塊版本使用的是 npm semver 規則(semantic version,npm 模塊依賴默認遵循的規則)。它并不嚴格規定版本,而是選擇符合當前 semver 規則的最新版本進行安裝。
一個簡單的例子:假如模塊 A 中依賴了 B,并且在 A 的 package.json 中指定 B 的 semver 為 ~1.2.3,那么所有形式為 1.2.x 的版本都是符合規則的。當模塊 B 更新了一個 1.2.x 的小版本后,項目在下次構建中就會獲取到它。
semver 這樣設計的初衷是使模塊的開發者可以將 bugfix 等微小的改動能更便捷地到達使用方。但它的負面影響卻是使每次 npm install 構建過程之間,項目內的模塊內容隨時可能發生改變。我們沒法確定在每個模塊內部,每一次小版本更新時究竟是加入了 bugfix,還是改變了 API,亦或是注入了惡意代碼。因此 left-pad 事件仍然可能出現。
3. Shrinkwrap - 使模塊不可變
由之前的討論可以看出,為了保證構建的可靠性,需要將 Java 模塊的版本固定下來,不允許在開發者不知情的情況下發生改變,這樣才能使每次構建的結果保持一致。其實在 npm 中利用 shrinkwrap 我們是可以做到這一點的。在項目中執行 npm shrinkwrap ,會根據當前 node_moduels 中已存在模塊的版本依賴信息生成 npm-shrinkwrap.json,當進行下一次構建時,會按照該文件中的版本信息從源上獲取,而不再使用 package.json 中的 semver 規則。shrinkwrap 文件的結構類似以下這種形式:
利用 shrinkwrap 我們可以保證構建的一致性,但是在實際使用中仍然存在一些問題。在較低版本的 npm 中,當我們執行模塊的添加、更新、刪除操作時,shrinkwrap.json 并不會自動同步,仍然需要手動執行 npm shrinkwrap,這無疑復雜了工作流程。假如某個項目成員忘記了手動同步,就會導致最終構建結果與預期不一致。另外 shrinkwrap 作為 npm 中一個非默認的構建模式,讓每個人接受和使用仍需要一定的學習成本。
目前 npm 社區中并沒有一個完備的工具能幫助我們自動生成和同步 shrinkwrap。Facebook 的 Sebastian McKenzie、James Kyle 等幾名工程師曾經嘗試過開發一個管理 shrinkwrap 的插件,然而由于種種原因效果并不理想。最終他們認為與其艱難地改進 npm 的基礎設施,不如直接推倒重來,于是之后有了我們現在看到的Yarn.
4. Yarn - 自動鎖定版本
Yarn 是 Facebook 公司在 2016 年 10 月 11 日開源的模塊管理器,它宣稱比 npm 更快、更安全、更可靠。Yarn 并不重頭建立一個新的 Java 模塊倉庫,而只是替代 npm 客戶端來管理原有的 node_modules 中的模塊,并彌補 npm 的缺陷。鑒于國情的原因,為了使用 Yarn ,我們需要把它的源指向國內,比如采用 cnpm 的源:
在 Yarn 中,鎖定版本號成為了一個默認行為。Yarn 會在項目中自動生成一個名為 yarn.lock 的文件,它與 npm shrinkwrap 的內容形式很相近,并且會隨著模塊的更新自動同步。這解決了在 npm 中我們需要手動添加和同步 shrinkwrap 的問題。當然,在項目構建時我們仍然可以選擇不使用 yarn.lock。加上 –no-lockfile 參數,模塊的安裝依舊會遵循 semver 規則。
5. 性能與體驗
npm 的速度慢一直是一個為人詬病的問題。在一個復雜的項目中執行 npm install,我們通常可以去倒杯咖啡,然后回來再看它是否完成了,對于漫長的等待已經習以為常。Yarn 為了解決速度問題,在構建時采用并行操作,優化了請求隊列,更高效地利用當前的網絡資源,同時 yarn.lock 也無形中減少了解析 semver 與獲取模塊最新版本的時間。另外,所有從源上獲取的模塊都會進行離線緩存,從而極大地加快重復構建的過程。
我在本地試驗了一個 React Native 的項目,同樣使用 cnpm 源,不采用任何緩存。npm 的構建花了 2 分 20 秒,而 Yarn 僅僅用了 1 分 16 秒就完成了,減少了近一半的時間。而利用 Yarn 的離線緩存機制進行重新構建,這次只用了 20 秒。Twitter 上一個名為 @timdorr 的開發者說,使用 yarn 可以讓他每周多出 30 分鐘開發時間。或許使用了 Yarn 之后,不會再有構建一次還有時間去倒咖啡的情形了。
在用戶體驗方面,運行 npm install 命令總是令我感到提心吊膽,因為它在構建過程中給出的信息實在不夠清晰,我并不知道它究竟在做什么(即使加了 --verbose)。有時它會停在某一步不再繼續運行,或是突然拋出一個難以追蹤的錯誤。而 Yarn 的構建提示明顯更加友好:
Yarn 會給出構建過程共有多少步,以及現在進行到了哪里。
如果拋出警告,Yarn 會告訴你該模塊的依賴關系(相比 npm 中只告訴你某個模塊有問題,然而當項目并沒有對其直接依賴,就很難進行定位了)。
在每個 Yarn 命令執行完成后,總會打出用時多少。
最后,Yarn 中有很多可愛的 emoji 表情。
執行 yarn install
6. 小結
總的來說,npm 仍然是當前最火熱的 Java 模塊管理器,但其歷史包袱或許阻礙了它為開發者提供更好服務的腳步。 Yarn 僅僅開源了一周,就已經在 Github 上被提了一大堆 issue,star 數也遠遠超過 npm,可見人們對于一個更好的模塊管理器已經期待已久。現在已經能看到在保證構建的可靠性與提升開發效率方面,Yarn 正在帶來積極的改變。在 Java 模塊管理器的更迭演進中,Yarn 邁出了向前的一小步。
對以上內容有疑問或需要交流的,歡迎留言,會及時回復大家。點擊閱讀原文,可以查看更多信息哦
不關注
就搗蛋
長按上方二維碼,關注“公眾號”
轉載請注明來自夕逆IT,本文標題:《速度解決:facebook登錄不上去,解決臉書頁面無法打開怎么辦?》

還沒有評論,來說兩句吧...