本文主要介紹前端開發中經常使用的包管理工具Bower,具體包括Bower的基本狀況、安裝、使用和常見命令等內容,最後還介紹了依賴樹管理的常見方式以及Bower採用的策略並進行了比較。前端

1.1 關於Bower

Bower是一款優秀的包管理器,它由Twitter公司開發,支持以命令行的方式來對包進行搜索、下載、更新和卸載。node

模塊或組件指獨立完整的模塊,能夠是應用的一部分或者是擴展,依賴能夠是jQuery或backbone這樣的庫,也能夠像Bootstrap這樣的UI框架或者是UI組件。jquery

英文(package)模塊或組件的另外一種叫法。git

依賴一個模塊爲了知足獨立完整原則所必須的其餘模塊,依賴提供了這個模塊所須要的功能,若是沒有這個功能,那麼這個組件就沒法工做。例如咱們認爲jQuery-ui這個組件依賴於jQuery。github

Bower的優勢npm

❑ 專爲前端開發設計,幾乎全部的主流前端庫均可以使用該工具。
❑ 約束鬆散,使用簡單。
❑ 依賴樹扁平更適合Web應用開發。json

官網參考:https://bower.io/vim

1.2 Bower的安裝

在安裝bower以前,必須確認你已經安裝了Node.jsGit瀏覽器

安裝Bower緩存

使用npm來安裝Bower,-g表示全局安裝

$ npm install -g bower

查看Bower版本

Bower安裝完成後就能在命令行中直接使用bower命令了,能夠經過下面的命令行來查看當前的版本。

$ bower -v 或者是$ bower -version

查看幫助信息

使用help命令來查看幫助信息。

$ bower -help

Usage:
 
bower <command> [<args>] [<options>]
Commands:
 
cache Manage bower cache(管理緩存信息)
help Display help information about Bower(顯示關於Bower的幫助信息)
home Opens a package homepage into your favorite browser
info Info of a particular package(顯示特定包的詳細信息)
init Interactively create a bower.json file(交互式建立bower.json文件)
install Install a package locally(安裝包到本地)
link Symlink a package folder(在本地bower庫創建一個項目連接)
list List local packages - and possible updates(列出本地包以及可能的更新)
login Authenticate with GitHub and store credentials(Github身份認證)
lookup Look up a single package URL by name(根據包名查詢包的URL)
prune Removes local extraneous packages(刪除項目沒有用到的包)
register Register a package(註冊一個包)
search Search for packages by name(經過名稱來搜索包)
update Update a local package(更新項目的包)
uninstall Remove a local package(移除項目的包)
unregister Remove a package from the registry(註銷包)
version Bump a package version(列出版本信息)
Options:...

1.3 Bower的使用

初始化操做

在桌面建立新的文件夾,用來演示Bower的使用。先使用命令行進入到文件夾路徑,而後使用下面的命令來對Bower進行初始化操做。

$ bower init

根據提示來交互式的設置基本項,初始化操做完成以後,會在文件夾的根目錄中建立一個bower.json文件,裏面包含一些基本信息。

{
"name": "bowerDemo",
"authors": [
"wendingding"
],
"description": "Nothing",
"main": "",
"license": "MIT",
"homepage": "wendingding.com",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

安裝指定的包 

嘗試執行下面的命令行,來把jQuery框架安裝到當前項目中。

$ bower install --save jquery

命令行中的save參數會把包記錄保存到bower.json文件中,install命令會把jQuery框架下載到bower_components目錄中,該目錄文件是保存全部組件和依賴的地方。當執行install命令的時候,Bower會從倉庫中獲取到jQuery組件的信息而後和bower.json文件中的信息進行比較,若是jQuery沒有安裝,那麼就會默認安裝最新版本,若是已經安裝了,則bower會自動中止並提示。

具體的執行狀況以下:

1 bogon:Demo wendingding$ bower install --save jquery
2 bower invalid-meta for:/Users/文頂頂/Desktop/Demo/bower.json
3 bower invalid-meta The "name" is recommended to be lowercase, can contain digits, dots
4 bower cached https://github.com/jquery/jquery-dist.git#3.3.1
5 bower validate 3.3.1 against https://github.com/jquery/jquery-dist.git#*
6 bower install jquery#3.3.1
7  
8 jquery#3.3.1 bower_components/jquery

命令執行完畢後,Bower會在根目錄下生成bower_components文件夾,並把下載好的包(jQuery框架)放在這個文件夾裏面。此時目錄結構以下: 

.
├── bower.json
└── bower_components
  └── jquery
├── AUTHORS.txt
├── LICENSE.txt
├── README.md
├── bower.json
├── dist
├── external
└── src

查看bower.json文件會發現,此時更新了包和對應的版本信息

"dependencies": {
"jquery": "^3.3.1"
}

1.4 Bower的常見命令Bower在執行安裝操做的時候,主要作了以下操做:

①  檢查項目目錄中的bower.json文件,以肯定包是否已經安裝了。
②  若是指定的包沒有安裝,那麼Bower就會檢查Bower倉庫中是否存在名稱對應的包
③  若是Bower倉庫中存在指定的包,那麼就下載最新版本到本地
④  把下載好的包的文件添加到項目目錄中,而且更新bower.json文件(包名和版本)

安裝指定包

1 $ bower install # 經過 bower.json 文件安裝
2 $ bower install jquery # 經過在github上註冊的包名安裝
3 $ bower install desandro/masonry # GitHub短連接
4 $ bower install http://example.com/x.js # URL路徑
5 $ bower install git://github.com/user/package.git #Github上的 .git

想要下載安裝的包能夠是GitHub上的短連接、.git 、一個URL路徑等。

搜索指定的包

$ bower search jquery

若是咱們在使用框架或者是框架插件的時候,記不住或者是不肯定包的名字,則能夠嘗試先經過關鍵字搜索,bower會列出包含關鍵字的全部可用包。

安裝包的指定版本

$ bower install --save jquery#1.8.0

Bower經過#號來肯定須要下載的版本,若是沒有指定版本,則Bower自動幫咱們下載最新的。因此,若是須要下載特定版本的包,能夠在安裝命令中使用#號來聲明。

若是要安裝指定的版本,也能夠先在bower.json文件中對dependencies選項進行配置,而後執行$ bower install或者是$ bower update命令。

查看已安裝的包

$ bower list
$ bower list --paths

具體的執行狀況以下

1 wendingding$ bower list
2 bower check-new Checking for new versions of the project dependencies...
3 demo /Users/文頂頂/Desktop/Test
4 ├── jquery#3.3.1
5 └─┬ jquery-ui#1.12.1
6 └── jquery#3.3.1
7 wendingding$ bower list --paths
8 jquery: bower_components/jquery/dist/jquery.js
9 jquery-ui': bower_components/jquery-ui/jquery-ui.js


卸載指定的包

list命令能夠查看項目中當前下載過的包,並提供最新版本號。
paths命令能夠查看當前下載過的全部包在項目中的對應路徑,在其它工具中須要聲明/配置前端依賴包地址的時候該命令可能會比較有用。

$ bower uninstall jquery

卸載本地項目中已經安裝的jQuery框架。

更新指定的包

$ bower update jquery

更新包的過程和安裝包的過程差很少,區別在於更新的時候會使用新文件替換舊文件,上面的命令強制安裝最新版本的jQuery框架。

查看指定包的詳細信息

$ bower info jquery

經過info指令能夠查看指定包的詳情,還指令會列出對應的git倉庫地址,以及全部可用的版本。

1.5 Bower安裝有依賴的包

一般當咱們使用Bower命令(bower install --save xxx)來安裝指定包的時候,Bower會查找包對應的git倉庫地址而後下載到本地並在bower.json文件中記錄版本等信息。但有的包在使用的時候可能存在依賴關係,好比ember這個包須要依賴於jQuery框架。

使用Bower安裝有依賴包的兩種方式
❑ 先安裝該包的依賴項(這裏爲jQuery),再安裝指定的包(這裏爲ember)
❑ 直接安裝(這裏爲ember)

   方式 ①    

先安裝依賴,再安裝指定包

$ bower install --save jquery
$ bower install --save ember
$ bower list

Test /Users/文頂頂/Desktop/Test
├─┬ ember#2.18.2 (latest is 3.0.0-beta.2)
│ └── jquery#3.3.1
└── jquery#3.3.1

直接安裝指定包,會自動安裝依賴(推薦)   方式 ②    

$ bower install --save ember

bower invalid-meta for:/Users/文頂頂i/Desktop/Test/bower.json
bower cached https://github.com/components/ember.git#2.18.2
bower validate 2.18.2 against https://github.com/components/ember.git#*
bower cached https://github.com/jquery/jquery-dist.git#3.3.1
bower validate 3.3.1 against https://github.com/jquery/jquery-dist.git#>=1.7.0<4.0.0
bower install ember#2.18.2
bower install jquery#3.3.1
ember#2.18.2 bower_components/ember
└── jquery#3.3.1
jquery#3.3.1 bower_components/jquery`

$ bower list列出項目中已經安裝的全部包和依賴關係

......
Test /Users/文頂頂/Desktop/Test
└─┬ ember#2.18.2 (latest is 3.0.0-beta.2)
 └── jquery#3.3.1


該命令行在安裝ember包的時候,發現須要依賴於jQuery框架,就會自動下載對應版本的jQuery框架並安裝到本地項目中。 

1.6 依賴樹管理

組件(包)並不是老是相互獨立的,有些組件(包)在使用的時候須要依賴於另一些組件(包),就像上文提到的ember須要依賴於jQuery,jQuery-ui須要依賴於jQuery同樣,咱們嘗試使用下面的圖示來描述這種關係。

上面的圖示揭示了包(組件)與包(組件)之間的依賴關係,很是簡單容易理解。在實際中,每一個組件可能都有多個依賴,而這些依賴本身可能還有別的依賴,或者多個不一樣組件都依賴於某個指定的組件,所以在處理的時候可能會很是複雜。爲了理清楚這複雜的關係,依賴管理工具會把全部的依賴構成一顆Dependency Tree(依賴樹)。

依賴樹主要有三種
❑ 嵌套依賴樹
❑ 扁平依賴樹
❑ 混合依賴樹

注意:在構造依賴樹的時候,組件(包)必需要有惟一的標識,該標識由組件的名稱和版本號構成,也就是說jQuery1.7.3和jQuery3.3.1是兩個不一樣的組件。

嵌套依賴樹

基本理念:每一個組件各自都有本身的依賴,而不會共用一個依賴。
主要問題:項目中會產生同一組件的多個副本,且可能有多個版本的組件共存比較混亂。

扁平依賴樹

基本理念:保證每一個組件在項目只有一個版本,沒有任何其它的副本。
主要問題:容易產生衝突,若是兩個組件須要同一個依賴的不一樣版本,就會致使出錯,必需要用戶本身來解決衝突,決定具體使用哪一個依賴並解決潛在的不一致性。

混合依賴樹

基本理念:使用最高效的辦法來管理一個組件的不一樣版本。
主要特色:混合依賴樹是扁平依賴樹和嵌套依賴樹的折中方案,若是一個組件的依賴已經安裝了,並且版本也兼容,那麼就沒必要再次下載安裝,只要指向已安裝的那個組件便可,若是版本不兼容的話,則下載安裝並版本兼容的組件。

1.7 Bower依賴樹管理和衝突處理

Bower做爲專爲前端開發者設計的依賴管理工具,是徹底基於扁平依賴樹的。上文介紹了扁平依賴樹在處理的時候要求保證每一個組件在項目只有一個版本,沒有任何其它的副本,優缺參半。那既然如此,Bower爲何不使用更高效的混合依賴樹?

Bower採用扁平依賴樹管理的緣由

(1)代碼體積對於前端開發很是重要,而扁平樹管理能夠實現組件最(少)小化。
(2)全部組件默認都在瀏覽器的全局做用域中運行,不一樣版本的同名組件會產生衝突。

由於Bower採用了扁平依賴樹的方式來處理,因此在使用的時候容易產生衝突,這種依賴管理方式要求開發者注重組件的版本兼容和依賴關係。接下來,咱們簡單演示Bower使用過程當中會出現衝突的狀況。

衝突的產生和處理

① 安裝jQuery框架的1.2.3版本

$ bower install --save jquery#1.2.3

執行狀況

1 bower invalid-meta for:/Users/文頂頂/Desktop/Test/bower.json
2 bower invalid-meta The "name" is recommended to be lowercase, can contain...
3 bower not-cached https://github.com/jquery/jquery-dist.git#1.2.3
4 bower resolve https://github.com/jquery/jquery-dist.git#1.2.3
5 bower download https://github.com/jquery/jquery-dist/archive/1.2.3.tar.gz
6 bower extract jquery#1.2.3 archive.tar.gz
7 bower deprecated Package jquery is using the deprecated component.json
8 bower resolved https://github.com/jquery/jquery-dist.git#1.2.3
9 bower install jquery#1.2.3

② 安裝ember組件並解決衝突 

$ bower install --save ember

具體的執行狀況

 1 bogon:Test wendingding$ bower install --save ember
 2 bower invalid-meta for:/Users/文頂頂/Desktop/Test/bower.json
 3 bower invalid-meta The "name" is recommended to be lowercase, can contain digits, dots, dashes
 4 bower cached https://github.com/components/ember.git#2.18.2
 5 bower validate 2.18.2 against https://github.com/components/ember.git#*
 6 bower cached https://github.com/jquery/jquery-dist.git#3.3.1
 7 bower validate 3.3.1 against https://github.com/jquery/jquery-dist.git#>= 1.7.0 < 4.0.0
 8  
 9 Unable to find a suitable version for jquery, please choose one by typing one of the numbers below:
10 1) jquery#1.2.3 which resolved to 1.2.3 and is required by Test
11 2) jquery#>= 1.7.0 < 4.0.0 which resolved to 3.3.1 and is required by ember#2.18.2
12  
13 Prefix the choice with ! to persist it to bower.json
14  
15 ? Answer 2
16 bower install jquery#3.3.1
17 bower install ember#2.18.2
18  
19 jquery#3.3.1 bower_components/jquery
20  
21 ember#2.18.2 bower_components/ember
22 └── jquery#3.3.1

說明咱們先把jQuery的1.2.3版本安裝到了項目中,而後又經過Bower來安裝ember,而ember組件須要依賴於jQuery框架,這裏有個關鍵信息就是ember要求依賴的jQuery框架版本範圍爲1.70 ~ 4.0.0和本地已經安裝的jQuery 1.2.3衝突,Bower並不會本身處理這個問題而是拋出一個異常,把選擇權交給用戶,由用戶來選擇使用哪一種方案。 

經過命令行的打印,咱們看到Bower爲咱們提供了兩個可選項,第一個選項是保留本地已經安裝的1.2.3版本,第二個選項是保存ember所依賴的版本,這裏顯示了依賴須要的版本範圍jQuery#>=1.70<4.0.0和最終會決定(resolved)的版本(3.3.1)。上面的示例中,衝突產生後咱們輸入2,選擇安裝jQuery的3.3.1版本。

③ 查看項目已安裝的組件信息

$ bower list

具體的組件和依賴結構

1 Test /Users/文頂頂/Desktop/Test
2 ├─┬ ember#2.18.2 (latest is 3.0.0-beta.2)
3 │ └── jquery#3.3.1
4 └── jquery#3.3.1 incompatible with 1.2.3 (1.2.3 available, latest is 3.3.1)


衝突處理完後,項目中本來下載安裝好的jQuery1.2.3版本被從新下載的3.3.1版本替代。 

1.8 Bower自定義組件目錄

默認狀況下,全部的依賴包都被下載保存到bower_components文件路徑,若是想要把依賴包下載到本身指定的目錄,使用.bowerrc文件配合bower.json就能夠實現。

在項目根目錄建立.bowerrc文件,使用json格式來設置文件路徑。
{ "directory": "指定路徑" }
保存好之後,執行bower install命令,就會把bower.json配置好的相關組件所有下載到指定的路徑中。

命令行參考

 1 bogon:Test wendingding$ touch .bowerrc
 2 bogon:Test wendingding$ vim .bowerrc
 3 bogon:Test wendingding$ cat .bowerrc
 4 {
 5 "directory": "app/xxx/"
 6 }
 7 bogon:Test wendingding$ cat bower.json
 8 {
 9 "name": "Test",
10 "authors": [
11 "flowerField <18681537032@163.com>"
12 ],
13 "description": "",
14 "main": "",
15 "license": "MIT",
16 "homepage": "",
17 "ignore": [
18 "**/.*",
19 "node_modules",
20 "bower_components",
21 "test",
22 "tests"
23 ],
24 "dependencies": {
25 "jquery": "^3.3.1"
26 }
27 }
28 bogon:Test wendingding$ bower install
29 bower invalid-meta for:/Users/文頂頂/Desktop/Test/bower.json
30 bower invalid-meta The "name" is recommended to be lowercase, can contain digits...
31 bower cached https://github.com/jquery/jquery-dist.git#3.3.1
32 bower validate 3.3.1 against https://github.com/jquery/jquery-dist.git#^3.3.1
33 bower install jquery#3.3.1
34  
35 jquery#3.3.1 app/xxx/jquery
36 bogon:Test wendingding$ tree -L 3
37 .
38 ├── app
39 │ └── xxx
40 │ └── jquery
41 └── bower.json