npm、bower、jamjs 等包管理器,哪個比較好用?

其他 js 的包管理:jamjs、volojs、component


@倪雲建 的回答不錯,在此作一些補充。

Bower

bower 的缺點比較明顯,最大的問題就是缺乏統一的構建機制。但有意思的是 Google 的 Polymer 選擇了 bower 作為包管理器,因為 Polymer 是建立在兩個還沒在瀏覽器里普遍實現的東西上的:HTML Import 和 SPDY。HTML Import 讓你可以把 HTML, CSS, JS 寫在同一個 HTML 文件里作為一個組件或是模塊,然後通過一行代碼引入:

&

同時,在一個組件里也可以引入其他的組件,也可以直接引用遠程伺服器上的組件。某種程度上 HTML import 可以取代現在的組件模塊機制。而 SPDY 是下一代的 http 協議,可以讓瀏覽器只用一個伺服器連接傳輸多個文件。換句話說即使你頁面里有很多個 HTML import 也不會因為多次請求導致頁面載入緩慢。在這兩個東西存在的理想情況下,前端項目是完全可以不需要構建過程的。這是 Bower 長遠來看的一個意義,但現階段對大多數開發者而言,構建依然是一個必不可少的步驟。

Component

曾經作為 TJ 腦殘粉的我是堅定的 component 使用者,但用了一段時間以後有幾個比較重要的不爽之處:

- 每一個 component 都必須要在 component.json 中手動列出所有文件,每次更改項目結構或是重命名文件都很麻煩,我還為此寫了個 grunt 插件專門自動做這個事情。

- component 只有一個 wiki page 列表,沒有一個可搜索的中央資料庫,模塊的可發現度比較低。同時,github 倉庫的星數是唯一的模塊質量指標,而 npm 則有下載統計和被依賴數量這些更實在的數據。

- 模塊發現度低帶來的另一個問題就是不同作者的模塊之間很少出現公用的依賴。雖然 Component 的依賴是扁平的,在實際使用別人的模塊的時候依然會出現重複(同樣的問題不同的實現),這就導致很多人寧可自己造輪子,自己依賴自己,只是把 Component 當個工具而不是平台用。

npm + Browserify

我這裡想要指出,npm 其實是一個非常好的前端(對,沒錯,是前端)包管理方案,最主要的就是依靠 Browserify 這個神器。Browserify 最大的意義不是讓你能在 npm 上發布前端的靜態資源,而是實現前後端的代碼共享。npm上有很多包是前後端通用的,比如我要找個現成的演算法實現,什麼 levenshtein distance 啊,perlin noise 啊,gaussian distribution 啊,A* 尋路啊,npm 上一搜一大把。常用的庫如 jquery backbone 之類的,只要你想得到的基本上都有 npm 版本。需要什麼直接 npm install 就可以用在瀏覽器端的項目里了,Component 和 Bower 在這方面跟 npm 完全沒有可比性,spm 就更不提了。開發流程上來說也極其省心,項目用 CommonJS 寫,不需要任何配置,給一個入口文件就行!還有一個官方工具 watchify,一行命令跑起,保存文件自動構建,連 grunt gulp 都不需要。

這個方案唯一的缺點,就是 npm 的樹狀依賴結構可能導致重複的模塊和代碼量的臃腫,需要跑一次 `npm dedupe` 來盡量壓平依賴樹。當然,實際情況中前端模塊出現依賴同一模塊的不兼容版本還是很少見的。


在當前的js包管理生態里,npm一統天下是早晚的事。然而我依舊不傾向於用npm管理前端包,並不是因為有更好的選擇,而是因為在我的實際使用中,npm還是存在一些邊界情況並不好使

大家都說思考的過程才是重要的,所以這裡我的主要目的是分享我在這方面的思考,並不給你一個推薦的工具( 因為就沒有我滿意的)

1. 前端、後端、腳本工具共享包可能會帶來一些不便

一個最常見的例子在於,線上部署的環境會追求穩定,而腳本工具的環境可以激進地使用新版,這包括了包的版本和Node本身的版本

那麼當 腳本工具追求新版本的庫的時候,同樣用了這個庫的前後端線上代碼要如何處理呢?npm並不允許頂層存在一個包的多個版本

假設線上的前端依賴著underscore 1.5.x,而現在我們的工具腳本發現1.7.x有不少很好用的函數,我們就要去做取捨

  1. 升級到1.7.x,那麼要進行回歸測試,同時線上的js緩存 可能因為僅僅一個庫的升級,在功能沒變化的情況下失效
  2. 不升級,本地的工具腳本繼續用1.5.x,那麼工具腳本的生產效率會下降

這個問題有另一個解決辦法,就是把repo本身進行拆分,工具腳本變成一個npm package,然而這並不好玩

2. npm並不能決定版本衝突時哪一個才是主版本

我們假設有這樣的依賴關係:

foo - underscore 1.5.x
alice - underscore 1.7.x
bob - underscore 1.7.x

我們需要安裝這三個庫,那麼underscore必然存在版本衝突,但是在npm3中哪個版本作為主版本(放在扁平化頂層)並不受控制

如果你的安裝順序是foo - alice - bob,那麼1.5.x將變成主版本,而alice和bob將各自擁有自己的underscore,這就導致一共出現了3次:

node_modules
├── alice
│ └── node_modules
│ └── underscore
├── bob
│ └── node_modules
│ └── underscore
├── foo
└── underscore

這顯然是一種浪費,因此我們需要自己去看各種依賴關係,然後決定安裝順序(根據上面的場景,其實應該是alice - bob - foo的順序安裝),npm在這點上並不透明,依賴複雜時並沒有為我們帶來特別明顯的福利

當然你可以說你不是強迫症,並不在乎這種重複,也不care體積上的問題,那麼如果這並不是underscore這種工具庫,而是一個有side-effect的庫又會怎麼樣呢?

3. 關於 源碼和構建產物的關係

前面有很多同學都說了,bower早期一大問題是直接從Git上拉取,很容易只拉到源碼而沒有構建過程

不過在這裡我其實一直有一個思考,就是如何對src和dist,甚至是bundle進行取捨。這在我最近做一個小lib的時候達到了巔峰:

  1. 如果只發布源碼,意味著使用者要對我的源碼進行構建,要知道構建需要什麼工具,無疑增加了使用成本,大家並不高興
  2. 如果只發布構建產物,那麼意味著我在構建過程中會產生冗餘信息,比如N個ES6編寫的庫如果要讓構建產物直接可用,就不能使用external-helpers參數進行babel編譯(所以我不明白babrel-preset-es2015-rollup為啥內置了這個plugin),那麼會產生複數的helper,這種冗餘帶來的代價對於大型系統來說並不好受
  3. 同樣的問題出在bundle和dist上,如果我發布一個bundle(把多個模塊搞成一個),那麼使用者如果有用不到的部分就很麻煩,基於UMD做tree shaking的技術並不成熟

所以最後我的選擇是,對於小的lib發布src + bundle,對於大點的lib發布src + dist,所以你看,src還是得發上去

而在大型的系統中,我更傾向於直接使用依賴庫的src(當然這很大程度上是因為我們大部分依賴庫是內部自己寫的,使用的工具體系相同,所以統一構建沒什麼壓力),來解決代碼冗餘等問題

4. npm提供的依賴類型不夠

這是個很現實的問題,事實上我們依賴一些第三方庫是為了干很多事,比如:

  1. 實際運行需要
  2. 進行構建需要
  3. 跑單元測試需要

但是npm只提供了production模式,只提供了dependencies和devDependencies的區分,這讓人很尷尬,一個實際我遇到的案例是:某個包依賴mocha + phantom進行單元測試,然而我們的npm包自動發布的web hook機安裝不上phantom,所以這個包再也沒有成功自動發布過……

我覺得npm應該適當地提供更多的依賴模式,比如給依賴進行定製化的分類管理,並且npm i --category=xxx控制安裝哪一部分會更好

5. 「反式依賴」功能的缺失

當然這並不是npm的弱點,至今並沒有任何一款包管理工具能完成這一功能(這也是我一直和我們的TC說包管理要自己做的一個原因)

這個我自創的「反式依賴」是什麼意思呢?我們試想一個場景

當前項目使用了react 0.14,現在項目需要react-tree這麼個組件

當我們使用npm i react-tree的時候,我們會得到什麼?

  1. 一個最新的react-tree版本
  2. 因為react-tree的最新版本的依賴是react 15.x,所以在react-tree內部有了自己的react

這是你想要的么,這個react-tree還能用么?而往往react 0.14升級到15.x幾乎是沒什麼可能的,你並沒有這麼多的精力和資源

所以我們更常做的是,先去翻一翻react-tree的版本,看看哪個版本是能用在react 0.14上的,然後指定這個版本安裝

這就是「反式依賴」,這裡的邏輯事實上是「先有了一個不能變化的主框架版本,其他依賴需要符合這個版本」,而這一功能是當前包管理工具都無法提供的,基於現在npm的包信息也很難實現這一功能

---

以上,我明白這些問題其實實際使用中並不會經常出現(甚至有些出現了大家也並沒有關注到),所以我並不反對使用npm進行前端包的管理,但以上例舉的問題是切實存在的,對於可能踩到這些坑的場景,還是要給予一些考慮的

補充一個我向我們的TC報告時對包管理的期待,這裡很多功能就是因為現有的包管理工具無法支持才會提出的


先說下前後端模塊管理的區別,後面會著重進行提到的這幾個前端模塊管理工具的比較和介紹。

npm屬於node模塊的管理器。而spm和bower是前端模塊管理。這兩者大的區別有兩點:

  1. NPM針對node模塊,原生支持commonJS,而前端模塊除非該管理器自己定了,否則規範是無法統一的。即便規定了commonJS,那麼必定會有配套工具打包來實現實際的運轉。
  2. 處理依賴的方式不同。NPM針對的node模塊,它的依賴是樹狀的。項目中用到的A,B,C三個模塊,他們可以分別依賴不同版本的lodash,而互不影響。但是前端模塊除非做了很好的模塊隔離(如實現了commonJS,並能很好地進行打包,即便如此,前端環境的特殊性也無法忍受相同模塊的不同版本並存。比如頁面中引入兩個版本的jQuery,代碼數據傳輸X2),否則一般的依賴都是扁平的。

當然,確實有很多人僅僅將npm作為一個靜態資源共享平台,用來發布和共享前端模塊,但是這種做法不推薦,因為顯然有更好的方案。

而spm和bower都是針對前端模塊化共享而提供的解決方案,這裡還有另一個比較有名的component ,TJ大神的作品。

下面詳細介紹bower,component以及spm:

一、Bower

twitter推出包管理工具。其特點是對包結構沒有強制規範,也因此bower本身並不提供一套構建工具,它充當的基本上是一個靜態資源的共享平台。

bower本身不存儲模塊文件本身(NPM以及SPM則會將模塊作者的文件打包保存在自己的伺服器中),也不保存模塊的版本信息。模塊的發布者通過註冊(register)的方式,將模塊的可訪問的公開的git地址記錄在bower的資料庫中。而所有的版本都是通過模塊發布者自己控制代碼庫的tag來決定。

bower在安裝流程基本上可以簡單認為是將註冊的git地址中的特定tag clone一份到你本地的bower_components 目錄中。

看起來bower本身提供的功能,以及實現都比價簡單,但是它確實使用最廣的前端模塊管理工具。它在github上的項目有1w+的star。之所以bower能這麼流行,得益於它寬鬆的規範能很好地直接應用在很多已經存在的項目中,所有人都能通過簡單地添加一個bower.json以及補充相關信息,不需要修改代碼和目錄結構,就馬上開始使用註冊發布自己的模塊。

二、component

(好吧,發現官網打不開了,我可是翻牆了....)

TJ大神的項目,它比bower提供了更多規範和配套工具:

  1. 它使用commonJS規範
  2. 它和bower一樣,不儲存模塊代碼,而是通過 github賬號名/模塊名 的方式作為一個模塊的標識符,是的,這句話的意思就是它的模塊都是在github上,進一步的意思是,你在github上新建一個public的倉庫的過程就是發布一個新模塊的過程,另外模塊down到本地後,也會帶上用戶名作為文件夾。對於有強迫症的人來說,這個有點抓狂,雖然這樣可以解決前端模塊重名的問題(比如,slide,tooltip這類幾乎每個合格的前端開發都自己早過一次輪子的組件,太常見了)
  3. 它在配置文件中,羅列出必要的靜態文件資源,因此在下載的過程中,是先抓去這個配置文件,然後再通過github的raw介面去抓取列出的文件。在傳輸效率上比bower的方式高效。且down下來的文件目錄也會比較簡潔。
  4. 既然1提到了它使用commonJS,那麼自然它也提供了配套的打包工具component/builder,打包工具包含的內容這裡不細講(要講可以額外再列一個如「有哪些好的前端構建工具推薦?」這樣的問題),主要有兩個特點:
    1. 基於commonJS規範
    2. 面向ES6(是的,你可以在componet中使用ES6的語法,而打包工具會幫你做好兼容,這也是component希望扮演的角色:"Component is currently a stopgap for ES6 modules and Web Components" )

附上 Compare component with other solutions

二、spm3

作為Sea.js - A Module Loader for the Web的生態圈的包管理工具,圍繞seajs而構建的,不僅包含模塊的發布,傳輸共享,還包含一系列的構建工具。

為什麼放到最後來講,因為如果仔細看SPM3(注意是3)的功能,它基本上是對bower,compoent和npm以及其他一些有名的包管理工具優點的吸收。這裡就說說我認為SPM3的優勢:

  1. SPM從3.X開始全面迎向CommonJS,逐步放棄CMD。CMD最有名的實現者是誰?SeaJS!是的,這裡是想說,一方面對於CommonJS支持,能很好地擴大SPM的社區(比如Component的模塊都能輕鬆地遷移過來),另一方面你會看到SPM3在打包上提供了Standalone 模式,不再依賴SeaJS
  2. 和NPM的發布一樣爽快的前端模塊管理平台。上面提到的bower和component本身都是不託管用戶的模塊代碼的,模塊的使用就是通過開發者自己維護倉庫和版本(打tag)。這樣的問題在於,對於一個模塊的實際版本是否穩定是難以保證的(我可以重複地去打相同的tag)而且代碼掌握在別人手裡穩定性難以保證(component使用github還是可靠,但是bower這種不限定git源的,就難說了)。在SPM中你可以使用如

    $ spm publish

    這樣的方式發布代碼了。

  3. 提供了一套完善的構建流程和工具,包含:
    1. 打包
    2. 調試
    3. 測試集成
    4. 文檔生成
  4. 支付寶團隊維護(支付寶自己在使用SPM,所以這個工具必定是經過實戰考驗的),中文文檔。這些對於國內用戶來說都是很重要的。

----------------- 總結 --------------------

bower

  1. 優點:約束鬆散,使用簡單--&> 可用模塊眾多
  2. 缺點:沒有提供構建工具(當前應該能從社區中找到針對bower的構建工具),且直接在bower上安裝模塊穩定性難以保證(源的穩定性,以及國內網速的穩定性)。

不過如果是公司級別內部使用的話,結合公司本身的git倉庫,並創建一個私有的bower server,並定製一套規範和打包工具,也是可行的。(好吧,這是我之前考慮過的在我廠內部實施的方案)

component

  1. 優點:基於commonJS,有比較完善的構建工具,面向ES6,且能解決命名衝突問題
  2. 缺點:基於github,目錄包含用戶名...(我個人無法忍)

spm

  1. 優點:託管模塊代碼,國內網路傳輸的穩定性(這個和bower以及component比起來就是很重要的優勢),完善的構建流程,中文文檔
  2. 缺點:模塊數量(目前是400多,和component以及bower的4位數比起來還是有差距)

建議題主都嘗試一下,再結合自己的場景做出選擇。


【2014年7月答】

bower 最流行,但是有一些重大的設計缺陷。

1. 所謂 module 格式的中立,是一件很投機取巧的事情。這可能是它流行的一個原因,但是從嚴肅的開發來說,最終你必然還是要選擇某種 module 格式。

2. bower 直接取 github 而缺少像 npm 那樣的 registry,導致一個問題,github上放的是源碼,和部署所需是不同的,這導致使用上的問題,你可以發現 bower 上的許多包都不是直接對應項目的 github 源碼庫,而是重新開個 repo 整理後放出來。

3. 依賴扁平這個事情,聽上去似乎是滿足前端的獨特性,但是如果仔細思考,就會發現,樹依賴其實比扁平依賴要複雜,從難入簡,肯定可以,反過來呢?

總之,雖然我們現在也在用 bower ,但是我已經在考慮是不是還是全用 npm,部分用 browserify 的方案。另外最近有一個未公開的項目 Duo,可能是作為下一代的 component (擦,1.0還沒出來多久……),號稱是結合了 browserify 和 component 的優點,是否能一舉反攻 bower,尚未可知。【2014年9月更新:duojs已經發布了:http://duojs.org/】

BTW,說一個我個人的感覺,基本上 twitter 出品的前端相關的項目儘管可能非常流行,都有一些本質上的設計缺陷。

【2015年11月更新】

一年過去了,bower現在處於四面楚歌的狀況。一些重要的項目的作者明確(語氣不善地)表示不會支持bower,比如babel、redux等,redux作者甚至斥之「bad for js ecosystem」。原因還就是我一年半以前說的那些,特別是第2點。另一方面其維護狀況也不容樂觀,其核心開發者只剩下一個!bower官方在尋求外部資源支持(包括開發者和資金贊助)。這件事情在最近一周持續發酵,連 @尤雨溪 提到的bower的著名成功案例Polymer(它不能通過npm安裝,僅能通過bower安裝)也表示2.0版會轉到npm3(switch from bower to npm? · Issue #2578 · Polymer/polymer · GitHub)。

總之,簡單的說,bower要丸。

回顧一下我講的三點吧。

我講的第一點,實際上雖然許多bower項目現在以UMD格式(可同時兼容commonjs、amd和global)發布,但是UMD仍然是前ES6時代的格式。隨著ES6 module和loader規範支持的臨近,bower的模塊格式將會再次成為問題。以這點來說反而是jspm更有前景。

我講的第二點,實踐證明確實增加了維護成本,這方面看babel的這個issue:Add bower.json to point to 6to5/polyfill · Issue #315 · babel/babel · GitHub ,redux的這個issue:Support installation via Bower · Issue #944 · rackt/redux · GitHub ,還有這個:Adding bower.json and uglified dist version by aendrew · Pull Request #359 · devongovett/pdfkit · GitHub ,這個:Please register to bower · Issue #1342 · mapbox/mapbox-gl-js · GitHub ……

我講的第三點,npm3現在的模塊目錄結構扁平了(但又保持了樹和依賴版本共存的可能性),這證明了我當時說的「從難入簡」易。且最近發布的node 5.0已經升級到了npm3,也就是npm3馬上將開始普遍可用。再加上webpack的崛起,使得用npm管理前端包變得非常常見——本問題下最近添加的兩個回答( @馮丹 和 @Colliot )都是這個意思。綜合來看,bower本來那些「優勢」已經蕩然無存了。


【2014.11.28 答】

首先表明立場,更喜歡bower,少數情況下npm更合適,不看好spm、component。

我的基本原則是,支持更靈活(約束更少)、專註(解決的問題明確)的,對應地,反對約束多、追求功能的大而全的。

反對 @尤雨溪 所說的

bower 的缺點比較明顯,最大的問題就是缺乏統一的構建機制

理由:

1. 統一的構建機制並不是包管理工具的職責,包管理器的核心價值在於解決依賴關係;構建工具很多,gulp、grunt、make都是。做自己的構建工具很容易陷入尷尬的境地:簡單的構建人家隨便用一兩個小工具就能搞定(uglify,cssmin,...),複雜的構建又不如gulp、grunt插件多、配置靈活(靈活是說gulp的,不包括grunt)

2. 前端module格式不統一,AMD/CMD、全局變數,甚至commonJS,如果要提供一個統一的構建機制,比如spm這種,那就首先得限制module格式;至少在目前,哪個格式會在以後一統天下並不明朗,(AMD使用很多,但commonJS看起來更有未來感,而很多時候一個簡單的工具直接在閉包裡邊運行,把結果暴露到全局變數上會更方便,避免額外的代價——AMD的模塊載入器或commonJS的代碼預處理),一個包管理器來對此進行限制並不是明智的行為,這也是我不喜歡/看好spm的原因

然後再反對 @賀師俊 「 module 格式的中立」是「重大的設計缺陷」(之一)的觀點。除了以上的第2點作為理由外,反駁

但是從嚴肅的開發來說,最終你必然還是要選擇某種 module 格式

一個項目完全可以以手動插入script標籤的形式引入jquery/zepto(or別的基礎庫),用AMD格式組織自己的代碼及一些其他依賴,我不覺得這有什麼不嚴肅的。對於模塊格式的選擇,更應該交給開發者自己。在還不存在一致、完美的方案前,引入依賴方式的多樣性可以獲得更大的自由度。

至於bower的優勢,他們都有提到,就不重複。

至於npm,首先,npm是node package manager的簡寫,它是為了解決nodejs的包管理而生的。用來進行前端模塊的管理,真的只是意外。npm的博客不久前有一篇博文,http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging,主要是闡述了npm官方對於前端包管理的觀點,大致表達四點:

1. 我們驚訝地發現,大家經常用npm管前端包!

2. 不過沒關係,npm當然是能用來做前端包管理的!

3. 前端包管理的形勢並不明朗,一些痛點還沒有也並不會被npm完美地解決

4. 他們不會在當前做出明確選擇,鼓勵大家有想法的話就動手做各種包管理器(最好基於npm),然後等群眾/開發者選出最好的

npm是有優點的,在於前後端代碼共享上,所以對於那些適用於各種javascript運行環境的庫來說吸引力更大,畢竟不需要在多個地方分別註冊、維護。不過除了這個不算很突出的優點外,存在安裝重複依賴及限制模塊格式的缺點。

為什麼不看好spm,不但模塊少,而且有強限制,而且我真的不喜歡用它的構建工具。

component的話,不熟悉,有種曲高和寡的感覺,而且TJ還「轉行」了。

【2015.11.19 補充】

正如 @hax 評論里說的,

一年過去了,bower現在處於四面楚歌的狀況。一些重要的項目的作者明確表示不會支持bower,比如babel、redux等。

被事實打臉後,決定回來分析一下為啥被打臉,以及先前的回答內容是不是還有意義。

首先,為啥被打臉。

不難發現,在我之前的答案中提到的幾個包管理器,spm 跟 component 其實活得比 bower 慘多了,處於基本沒有存在感的狀態。唯一的例外是 npm,所以出乎我本來預料的是 npm 在前端包管理領域幹掉了 bower。可以說 npm 做了一次相當成功的轉型,從 node package manager 到 javascript(-relative) package manager,這次轉型的成功我覺得有以下三點原因:(以我認為的重要性從大至小排序)

1. browserify、webpack 等支持 CommonJS 規範的構建工具的流行

這促進了前端代碼的 CommonJS 化,即越來越多,即使是使用場景僅限瀏覽器端的包開始使用 CommonJS 規範組織代碼,避開了過去流行的「立即執行函數」、AMD 等格式的 JS 代碼放在 npm 包里的不倫不類(甚至是醜陋)。

2. npm 自己的努力

在我之前的答案里也提到,npm 也是希望自己可以被用於前端包管理的,不過(當時)仍存在「安裝重複依賴及限制模塊格式的缺點」,後者即第一點裡提到的,被 browserify、webpack 等解決了;後者則是 npm 自己努力在解決。

3. bower 不爭氣啊

如「bower 直接取 github 而缺少像 npm 那樣的 registry」,這確實是一個明顯的缺陷。而時至今日我並沒有看到 bower 團隊在這方面改進的努力。

然後,來說說,先前的回答內容是不是還有意義。

我認為是有的,其中兩個主要觀點:

首先, 「統一的構建機制並不是包管理工具的職責,包管理器的核心價值在於解決依賴關係」,只能說目前的發展進一步證實了我的這個觀點,包管理是包管理,構建工具是構建工具。

其次,關於「module 格式的中立」是不是設計缺陷,我依然覺得不是(至少在目前來說), webpack、jspm 等支持多種 module 格式的構建工具的流行亦是證明。

最後,更新我的結論為:目前 npm 是最好用的 Javascript 包管理工具,不管是前端還是後端。


我會選擇npm,有了browserify這個神器,npm真的可以作為前端的包管理器。 npm倉庫里好多包都是前後端通用的,而且常用的前端庫在npm都有。比沒有registry的bower好太多了。


有了 Webpack 之後,更加沒有爭議了。npm 無疑。

你要把 JavaScript (ES5 or 3?) 當成目標代碼,V8 當成一個平台,這一切就容易理解了。無論你是寫 CoffeeScript, ES6/7 還是 TypeScript,乃至是 CSS/Less/Scss,甚至圖片、字體,都可以通過中間流程融為一體,只要你遵循了某種模塊規範,比如 CommonJS。甚至 IDE 都能互相 resolve 模塊,就好比 Scala 和 Java 混寫一樣。

這是網路應用開發工程化可喜而偉大的一步。


關於 component ,首先它的設計目標並不是易用,而是實現的簡潔(代碼以及API),也就是為了乾淨的代碼犧牲一定程度的易用性,再加上缺乏文檔以及統一的倉庫等原因就導致了它基本只會是一個小眾的工具。結果就是關注流行的初學者不太願意用它,但對於有經驗的開發人員這種簡潔的設計有著巨大的意義,那就是相對低的多的後續維護成本,因為代碼很容易理解,修改和擴展代碼的行為就變得容易的多,而代碼維護對於長期項目而言要比初次開發重要的多。其次,component 不僅僅是做包管理的,它也是一套簡潔的構建工具,通過使用 Makefile 構建腳本,相比 grunt gulp 那些醜陋的 API 簡潔的多。

我沒法告訴你哪個工具更好,但我想大概可以這麼選:

  • 想要前後端通用,選 npm + browserify
  • 追求代碼簡潔和高質量模塊,選 component
  • 想快速上手解決問題,選 bower
  • 忠實國產粉絲,選 spm (呵呵,它還是蠻多優點的)


前端 自從node 出來之後,各種工具 庫 百花齊放

----------分-------

如樓上 @謝鵬 同學的解釋。

bower 和 npm 對於我來說 一直用的比較順手的npm 它的出現是和 node 有很大關係,既然我們要跟隨node的腳步,那麼 npm 應該錯不了,而且 也沒功夫,去斟酌哪個工具的好用程度,具體需求,具體分析。

很喜歡 某前端大牛的做法,盡量選擇 只做一件事,做好一件事的包 來協助前端開發。


感覺還是比較喜歡npm,未來的趨勢肯定是規範的統一,前後端模塊差不多都可以通用.


如果一定要比的話,npm 最好用。

npm 是 node 的包管理。

spm 是 seajs 的包管理吧?已經不更新了,放棄吧。

bower 是有 twitter 的人在支持,而且現在很多工具鏈都帶上了他,可以進入。

jamjs 是 async.js 的作者 caolan 的作品,放棄吧。

volojs 沒聽說過。

component 有潛力,但是還沒起來,觀望中。tj 走了,也不懂現在誰在推這東西。


npm + webpack 什麼都不說了


他們做的事情,明顯不一樣。

npm是nodejs的包管理。

spm主要是適用於seajs的包管理。

bower是前端庫的包管理。

怎麼放在一起比較?


spm 從 3.9 開始將不再管理組件的生命周期, 即不再有 spmjs.io. 所以相應的邏輯全部去除. 請使用 npm 來管理組件.

下載安裝spm感覺好慢啊,不再愛了


當談論什麼包管理器好用的時候,不妨動手試一試。

手動推薦,npm。

1、包多

2、包全

3、社區大

4、國際化

5、文檔優質


補充一點, 雖然我們在用bower, 但我一直在想把它換掉。

bower最無語的一點是, 註冊的庫無法編輯和刪除, 必須在官方的issue的某個帖子裡面留言, 等待人工操作, 上次我的一個庫的github地址變更, 等了一個月。


吐槽下npm一個比較坑的地方,就是一個普通的前端包的依賴樹非常冗長,文件層級太深以至於在Windows系統下,有時候手賤想刪除卻無法刪除的問題……


npm的視頻講解地址INTA課程主頁


推薦閱讀:

js 數組賦值問題 :值傳遞還是引用?
在自學前端,但是沒有什麼實踐的資源,大家來推薦一下論壇或者別的可供練習的資源吧?
JS立即執行如何使用?還是說圓括弧本身是用來改變JS的執行上下文環境?
js 中,不使用數組,不使用對象,可以 return 多組值嗎?
TypeScript 的命運會不會和 CoffeeScript 一樣 ?

TAG:前端開發 | JavaScript | Nodejs | npm | bower |