Bower

References

https://github.com/bower/bower
https://bower.io/
API: https://bower.io/docs/api/
bower.json specification

作用

前端 javascript 包管理器,和 maven 类似;与 npm 的区别是,npm 管理的是 NodeJs 模块,而 bower 管理的是前端 javascript 第三方模块,两者做的事情相同,但是服务的对象不同。

使用

Bower Install

1
$ npm install -g bower

Create bower.json

bower.json 类似于 package.json,pom.xml 等,包和包依赖相关的描述文件。创建 bower.json。

1
$ bower init

一路回车,最后生成 bower.json 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
? name bower
? description
? main file
? keywords
? authors shangyang <comedshang@163.com>
? license MIT
? homepage
? set currently installed components as dependencies? Yes
? add commonly ignored files to ignore list? Yes
? would you like to mark this package as private which prevents it from being accidentally published to the registry? No
{
name: 'bower',
authors: [
'shangyang <comedshang@163.com>'
],
description: '',
main: '',
license: 'MIT',
homepage: '',
ignore: [
'**/.*',
'node_modules',
'bower_components',
'js/lib',
'test',
'tests'
]
}

bower.json specification

Install Packages

更详细的内容,参考Bower Install

bower 将会把包默认安装到本地目录 bower_components/ 中。(官网的描述不对,当前版本的 bower 是将包安装到 js/lib 中的,可以通过 .bowerrc directory 属性配置将其重定向到其它的目录中。

1
$ bower install <package>

各种安装包的方式,GitHub shorthand, a Git endpoint, a URL, and more.

1
2
3
4
5
6
7
8
9
10
\# installs the project dependencies listed in bower.json
$ bower install
\# registered package
$ bower install jquery
\# GitHub shorthand
$ bower install desandro/masonry
\# Git endpoint
$ bower install git://github.com/user/package.git
\# URL
$ bower install http://example.com/script.js

Search Packages

Search Bower packages and find the registered package names for your favorite projects.

创建 Package

意义

将你的 javascript 打包成一个包,就等价于 java 中的 .jar

bower.json

Packages are defined by a manifest file bower.json. This is similar to Node’s package.json or Ruby’s Gemfile.

Interactively create a bower.json with [bower init](#Bower Init)

bower.json就相当于pom.xml在 maven 中的地位。参考bower.json specification

创建 bower.json

1
$ bower init

bootstrap 中 bower.json 样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
name: 'bootstrap',
version: '3.0.0',
main: [
'./dist/js/bootstrap.js',
'./dist/css/bootstrap.css'
],
ignore: [
'**/.*'
],
dependencies: {
jquery: '>= 1.9.0'
},
homepage: 'https://github.com/twbs/bootstrap'
}

main属性
我翻遍了官方文档,google、百度了半天,也没发现对这个属性的半点解释,不过,从 bootstrp 的 bower.json 中不难发现,应该指的是该 component 的入口文件,当 component 有多个 js 文件的时候,那么很显然,需要指定入口文件;相当于 Java 的 Main Class。

Maintaining dependencies

Using bower install <package> --save will add <package> to your project’s bower.json dependencies array.

1
2
\# install package and add it to bower.json dependencies
$ bower install <package> --save

Similarly, using bower install <package> --save-dev will add to your project’s bower.json devDependencies array.

1
2
\# install package and add it to bower.json devDependencies
$ bower install <package> --save-dev

Register

将你的包注册为一个可以被 bower install <package> 方式获取的包。

1
2
3
$ bower register <my-package-name> <git-endpoint>
\# \for example
$ bower register example git://github.com/user/example.git

这样,任何人都可以通过bower install <my-package-name加载你的包了。(哈哈,原来 javascript 的 programmer 都这么玩的,是要比 maven 简单许多 )

For private packages (e.g. GitHub Enterprise), please consider running a private Bower registry.

详情参考 https://bower.io/docs/creating-packages/#register

Unregister

1
2
3
4
5
6
bower login
\# enter username and password
? Username:
? Password:
\# unregister packages after successful login
bower unregister <package>

API

Commands

Bower Cache

管理 Bower 的缓存

1
$ bower cache <command> [<args>]

cache clean

1
2
3
$ bower cache clean
$ bower cache clean <name> [<name> ...]
$ bower cache clean <name>#<version> [<name>#<version> ..]

cache list

1
2
$ bower cache list
$ bower cache list <name> [<name> ...]

1
2
3
4
5
6
7
8
9
10
11
12
$ bower cache list
angular=https://github.com/angular/bower-angular.git#1.6.2
angular-animate=https://github.com/angular/bower-angular-animate.git#1.6.2
angular-cookies=https://github.com/angular/bower-angular-cookies.git#1.6.2
angular-mocks=https://github.com/angular/bower-angular-mocks.git#1.6.2
angular-resource=https://github.com/angular/bower-angular-resource.git#1.6.2
angular-route=https://github.com/angular/bower-angular-route.git#1.6.2
angular-sanitize=https://github.com/angular/bower-angular-sanitize.git#1.6.2
angular-touch=https://github.com/angular/bower-angular-touch.git#1.6.2
bootstrap=https://github.com/twbs/bootstrap.git#3.3.7
bootstrap-sass=https://github.com/twbs/bootstrap-sass.git#3.3.7
jquery=https://github.com/jquery/jquery-dist.git#3.1.1

可见,本地会缓存很多的 js 文件;官网上没有对这些 cache 做进一步解释,如何存储?为什么要缓存?我猜测,是不是放在内存里的?我的猜测是错误的,答案在使用本地缓存

Bower Help

1
$ bower help <command>
1
2
3
4
5
6
7
8
9
$ bower help cache

Usage:

bower cache <command> [<args>] [<options>]
Commands:

clean Clean cached packages
list List cached packages

Bower Home

1
2
3
$ bower home
$ bower home <package>
$ bower home <package>#<version>

Opens a package homepage into your favorite browser.

1
$ bower home jquery

将会使用浏览器打开 jquery 的官网地址,这里打开的是 https://github.com/jquery/jquery-dist

Bower Info

Displays overall information of a package or of a particular version.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ bower info jquery
bower jquery#* cached https://github.com/jquery/jquery-dist.git#3.1.1
bower jquery#* validate 3.1.1 against https://github.com/jquery/jquery-dist.git#*

{
name: 'jquery',
main: 'dist/jquery.js',
license: 'MIT',
ignore: [
'package.json'
],
keywords: [
'jquery',
'javascript',
'browser',
'library'
],
homepage: 'https://github.com/jquery/jquery-dist',
version: '3.1.1'
}

Available versions:
- 3.1.1
- 3.1.0
...
...

Bower Init

1
$ bower init

交互式的生成 bower.json 文件

Bower Install

1
2
$ bower install [<options>]
$ bower install <endpoint> [<endpoint> ..] [<options>]

Endpoints can have multiple forms:

1
2
3
<package>
<package>#<version>
<name>=<package>#<version>

使用

》可以不接任何的参数,直接调用如下指令,将会根据 bower.json 中所描述的依赖进行加载

1
$ bower install

》加载最新版本的包

1
$ bower install jquery

这里会成功安装3.1.1最新版本的 jquery。安装完成以后包路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.
├── bower.json
└── js
└── lib
└── jquery
├── AUTHORS.txt
├── LICENSE.txt
├── README.md
├── bower.json
├── dist
│   ├── core.js
│   ├── jquery.js
│   ├── jquery.min.js
│   ├── jquery.min.map
│   ├── jquery.slim.js
│   ├── jquery.slim.min.js
│   └── jquery.slim.min.map
├── external
│   └── sizzle
│   ├── LICENSE.txt
│   └── dist
│   ├── sizzle.js
│   ├── sizzle.min.js
│   └── sizzle.min.map
└── src
├── ajax
│   ├── jsonp.js
│   ├── load.js
│   ├── parseXML.js

注意,通过bower安装以后,是将 package 安装到路径 js/lib 中的

》加载指定版本的包,使用

1
$ bower jquery#3.0.0

因为之前安装过最新版本的 jquery 3.1.1,所以,这里安装的时候会提示冲突,并提示如何解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bower jquery#3.0.0          not-cached https://github.com/jquery/jquery-dist.git#3.0.0
bower jquery#3.0.0 resolve https://github.com/jquery/jquery-dist.git#3.0.0
bower jquery#3.0.0 download https://github.com/jquery/jquery-dist/archive/3.0.0.tar.gz
bower jquery#3.0.0 extract archive.tar.gz
bower jquery#3.0.0 resolved https://github.com/jquery/jquery-dist.git#3.0.0

Unable to find a suitable version of jquery, please choose one by typing one of the numbers below:
1) jquery#3.0.0 which resolved to 3.0.0
2) jquery#^3.1.1 which resolved to 3.1.1 and is required by bower

Prefix the choice with ! to persist it to bower.json

? Answer !1
bower jquery resolution Saved jquery#3.0.0 as resolution
bower jquery#3.0.0 install jquery#3.0.0

输入!1表示使用 jquery 3.0.0,那么,3.0.0 将会替换 js/lib 中的 3.1.1

》推荐使用--save

1
$ bower jquery --save

When --save flag is used, all additional endpoint are saved to dependencies in bower.json. 额外的 endpoint(就是指一个包) 同样会被保存。
Bower recommends to always use --save flag to achieve reproducible installs between machines.

install options

  • -F, --force-latest: Force latest version on conflict
  • -p, --production: Do not install project devDependencies
  • -S, --save: Save installed packages into the project’s bower.json dependencies
  • -D, –save-dev: Save installed packages into the project’s bower.json devDependencies
  • -E, –save-exact: Configure installed packages with an exact version rather than semver
1
2
$ bower link
$ bower link <name> [<local name>]

The link functionality allows developers to easily test their packages. Linking is a two-step process.

Using ‘bower link’ in a project folder will create a global link. Then, in some other package, bower link <name> will create a link in the components folder pointing to the previously created link.

This allows you to easily test a package because changes will be reflected immediately. When the link is no longer necessary, simply remove it with bower uninstall <name>.

对,你看完官网的阐述以后,大概也不清楚blow link到底能干什么…(看官网文档最痛苦的莫过如此,看了,还是云里雾里)

http://stackoverflow.com/questions/28242944/grunt-watch-bower-link-what-is-the-most-appropriate-way-to-use-grunt-watch-with
这篇文章中,大致介绍了如何使用 bower link;它的目的应该是,当你在通过 bower 开发你的 bower component的时候,对你正在开发的bower component设置一个bower link,这样,在别的component中就可以直接引用你当前该正在开发的bower component了;是的,如果按照 bower 的正常发布的流程,那么你必须使用bower install <package>的方式来进行加载,但是,这样的做法只适已经 released 的包,不适合正在开发中的包。等等,扯了这么一大堆,这个东西不就等价于 java project reference 吗?

Bower list

1
$ bower list [<options>]

List local packages and possible updates.

bower list等价于bower list -r,好处是,可以显示出包的版本

1
2
3
4
$ bower list
bower check-new Checking new versions of the project dependencies...
bower /Users/mac/workspace/javascript/bower
└── jquery#3.1.1

bower list -p,好处是,可以显示当前安装路径信息,坏处是不显示版本信息

1
2
3
4
$ bower list --paths
{
"jquery": "js/lib/jquery/dist/jquery.js"
}

list options

-p, --paths: Generates a simple JSON source mapping
-r, --relative: Make paths relative to the directory config property, which defaults to bower_components

1
2
3
$ bower list --path

jquery: 'js/lib/jquery/dist/jquery.js'

会显示 jquery 的安装路径在哪里。

1
2
3
4
$ bower list -r
bower check-new Checking new versions of the project dependencies...
bower /Users/mac/workspace/javascript/bower
└── jquery#3.1.1

看来bower list默认执行的是bower list -r

Bower lookup

1
$ bower lookup <name>

Look up a package URL by name,显示包的 URL 地址

1
2
$ bower lookup jquery
jquery https://github.com/jquery/jquery-dist.git

Bower login

1
$ bower login

Authenticate with GitHub and store credentials. Required to unregister packages.

login options

-t, --token: Pass an existing GitHub auth token rather than prompting for username and password

Bower prune

1
$ bower prune

Uninstalls local extraneous packages;移除本地多余的包

Bower Register

1
$ bower register <name> <url>

Register a package, 参考Register

是指在 Bower 中心中注册?是的。

1
2
$ bower search
$ bower search <name>

Finds all packages or a specific package.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ bower search jquery
Search results:

jQuery https://github.com/jquery/jquery.git
jquery https://github.com/jquery/jquery-dist.git
jquery.x https://github.com/jljLabs/jquery.x.git
jt_jquery https://github.com/vicanso/jt_jquery.git
jquery.Q https://github.com/jsbuzz/jQuery_Q.git
jquery-m https://github.com/meetup/jquery.git
jquery.j2d https://github.com/fsggs/jquery.j2d.git
jquery.hx https://github.com/millennialmedia/jquery.hx.git
jquery-ts https://github.com/andraaspar/jquery-ts.git
jquery-tm https://github.com/trymore/jquery-tm.git
jquery.gk https://github.com/ezoapp/jquery.gk.git
jquery-jec https://github.com/RaYell/jquery-jec.git
no-jquery https://github.com/Merott/no-jquery.git
hg-jquery https://github.com/HackerGaucho/hg-jquery.git
dt-jquery https://github.com/jedmao/dt-jquery.git
jquery-fb https://github.com/amitab/jQueryFB.git
sw-jquery https://github.com/sowirepo/jquery1.8.3.git
jquery-ui https://github.com/components/jqueryui.git
jquery.up https://github.com/tonekk/jquery.up.git
jquery-py https://github.com/seandong/jquery-py.git
Rx-jQuery https://github.com/Reactive-Extensions/rxjs-jquery.git
jquery.ui https://github.com/jquery/jquery-ui.git
jquery.os https://github.com/suprMax/jquery.os.git
jquery-ol https://github.com/jordanmarkov/jquery-ol.git
jquery.ua https://github.com/cloudcome/jquery.ua.git
hn.jquery https://github.com/loi-chuanoi/jquery.git
jquery2 https://github.com/iki/jquery2.git
jqueryp https://github.com/Ensighten/jqueryp.git
jquery-rss https://github.com/sdepold/jquery-rss.git
jquery.bem https://github.com/zenwalker/jquery-bem.git

Wow! 原来是从 Github 中搜索所有 jquery 相关的 git 项目。

Bower update

1
$ bower update <name> [<name> ..] [<options>]

Updates installed packages to their newest version according to bower.json.

update options

-F, –force-latest: Force latest version on conflict
-p, –production: Do not install project devDependencies
-S, –save: Update dependencies in bower.json
-D, –save-dev: Update devDependencies in bower.json

这里阐述一下如何升级才能生效,首先,修改bower.json,将要升级的包改为指定版本,然后,执行bower update,这样,bower会根据bower.json中的版本,自动将包更新为指定的版本。注意,不要被udpate关键字给迷惑了,同样可以向低版本更新。
(其实,这就和 maven 的做法相同,修改 pom.xml,然后执行一次 maven update

Bower uninstall

1
$ bower uninstall <name> [<name> ..] [<options>]

Uninstalls a package locally from your _bower_components_ directory (备注,当前版本的 bower 使用的路径是 js/lib)

uninstall options

  • -S, –save: Remove uninstalled packages from the project’s bower.json dependencies
  • -D, –save-dev: Remove uninstalled packages from the project’s bower.json devDependencies
  • 不使用 options

    1
    $ bower uninstall jquery
    1
    2
    3
    4
    $ bower list
    bower check-new Checking \for new versions of the project dependencies...
    bower /Users/mac/workspace/javascript/bower
    └── jquery not installed
    1
    2
    3
    4
    5
    $ tree
    .
    ├── bower.json
    └── js
    └── lib

    可见 bower.json 里面有关 jquery 的配置文件并没有被删除

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    {
    "name": "bower",
    "authors": [
    "shangyang <comedshang@163.com>"
    ],
    "description": "",
    "main": "",
    "license": "MIT",
    "homepage": "",
    "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "js/lib",
    "test",
    "tests"
    ],
    "dependencies": {
    "jquery": "^3.0.0"
    }
    }
  • 使用 options

    1
    $ bower uninstall jquery --save

    这下,bower.json 中有关 jquery 的信息也被清理干净了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    {
    "name": "bower",
    "authors": [
    "shangyang <comedshang@163.com>"
    ],
    "description": "",
    "main": "",
    "license": "MIT",
    "homepage": "",
    "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "js/lib",
    "test",
    "tests"
    ],
    "dependencies": {}
    }

Bower unregister

see Unregister

Bower version

1
$ bower version [<newversion> | major | minor | patch]

Run this in a package directory to bump the version and write the new data back to the bower.json file.

The newversion argument should be a valid semver string, or a valid second argument to semver.inc (one of “build”, “patch”, “minor”, or “major”). In the second case, the existing version will be incremented by 1 in the specified field.

If run in a git repo, it will also create a version commit and tag, and fail if the repo is not clean.

version options

  • -m, --message: Custom git commit and tag message

If supplied with --message (shorthand: -m) config option, bower will use it as a commit message when creating a version commit. If the message config contains %s then that will be replaced with the resulting version number. For example:

1
$ bower version patch -m "Upgrade to %s for reasons"

意思就是为当前的bower component添加版本号。

semver string,什么是 semver string? 全称是Semantic Versioning,由 MAJOR、MINOR、PATCH 构成,MAJOR 表示有与之前版本不兼容的版本产生,MINOR 表示提供了新功能且与当前版本兼容,PATCH 表示修复了 BUG;举例 2.3.15,表示主版本号为 2(与 1 不兼容),次要版本号为 3(有新功能添加并且与当前主要版本 2 兼容),PATCH 号表示 BUG 修复的次数。完整解释,参考 http://semver.org/

Options

force

1
-f, --force
  • bower install --force 强制重新安装所有已安装的包;并且自动加载到 cache
  • bower uninstall <package> --force 即便是有包依赖关系,同样强制删除。
  • bower register <package> --forcebower unregistr <package> --force将会省略掉确认提示;Login 过程仍然需要

json

1
-j, --json

返回 human readable 的文档,Output consumable JSON

1
2
3
4
$ bower list --path --json
{
"jquery": "js/lib/jquery/dist/jquery.js"
}

将输出格式转换为 json 格式。

loglevel

1
-l, --loglevel

What level of logs to report. Possible values: error, conflict, warn, action, info, debug

offline

1
-o, --offline

Do not use network connection

quiet

1
-q, --quiet

Only output important information. It is an alias for --loglevel=warn.

silent

1
-s, --silent

Do not output anything, besides errors. It is an alias for --loglevel=error. Silent is also useful if you have private components that might leak credentials to your CI environment.

verbose

1
-V, --verbose

Makes output more verbose. It is an alias for --loglevel=debug.

allow-root

1
--allow-root

Allows running commands as root. Bower is a user command, there is no need to execute it with superuser permissions. However, if you still want to run commands with sudo, use --allow-root option.

持续集成

Bower will skip some interactive operations if it finds a CI environmental variable set to true.

You may try to set the CI variable manually before running your Bower commands. On Mac or Linux, export CI=true and on Windows set CI=true

If for some reason you are unable to set the CI environment variable, you can alternately use the --config.interactive=false flag.

1
$ bower install --config.interactive=false

为什么在CI过程中非要停止bower的交互功能呢?难道不能通过Grunt脚本来控制?

使用本地缓存

Bower supports installing packages from its local cache – without an internet connection – if the packages were installed before.

1
$ bower install <package> --offline

The content of the cache can be listed with bower cache list:

1
$ bower cache list

The cache can be cleaned with bower cache clean:

1
$ bower cache clean

Ok,为了支持离线加载,所以才把包缓存在本地;那应该是放置在其它的 tmp 文件中。

.bowerrc

通过.bowerrc提供额外的配置信息,比如环境变量,等等 https://bower.io/docs/config/

directory

1
2
3
{
"directory": "bower_components"
}

当前版本的 bower,默认将包放置在js/lib目录中,通过设置 directory 属性,可重定向

Grunt

https://bower.io/docs/tools/

  • grunt-bower-concat
  • grunt-wiredep

    Inject your Bower components right into your HTML using Grunt.

  • grunt-bower-requirejs
  • grunt-bower-task
  • grunt-preen

例子

按照使用章节配置好初始化环境以后,执行

1
2
3
4
$ bower install jquery --save
bower jquery#* cached https://github.com/jquery/jquery-dist.git#3.1.1
bower jquery#* validate 3.1.1 against https://github.com/jquery/jquery-dist.git#*
bower jquery#^3.1.1 install jquery#3.1.1

可见,安装的是当前最新版本的jquery;注意,安装包是放置在本地js/lib目录中的,而不是官方中所描述的那样默认放置在 bower_components/,TODO, 这个问题有待澄清。Ok,澄清了,可以通过 .bowerrc directory 属性进行定制化的配置。

Bower 生死边缘

https://ruby-china.org/topics/28060
该篇文章描述了,由于 webpack 等工具的产生,使得 NPM 一个管理 NodeJs 模块的工具也完全能够胜任 Bower 的工作了,使得前端 Javascript 代码能够模块化,并且以模块化的方式进行管理。最核心的部分摘录如下,

我的看法:bower的确只解决了包和依赖下载的问题,但是它的配置文件bower.json中也定义了包和包的依赖关系,通过这层关系,其实就非常容易实现包加载顺序的问题了;最核心的部分包依赖关系已经被bower规范化了以后,所以,才有了grunt-wiredep这样轻量的 grunt 模块三两下就把包加载顺序解决了。所以,上面 darkbaby123 所说的论点,不敢完全赞同。不过,识时务者为俊杰,可见,当前的潮流是往NPM上统一,这点上,我是赞成的,如果能够通过一个NPM包和依赖管理工具解决所有的问题,何乐而不为呢?所以,由此看来,学习webpack势在必得呀..