Package managers simplify installing and updating project dependencies, which are libraries that it uses: jQuery, Fotorama, everything that is used on your site and isn’t written by you.
Browsing all the library websites, downloading and unpacking the archives, copying files into the
Many programming languages have standard package managers, which developers use to install all libraries: gem for Ruby, pip for Python and others. For server-side JavaScript there is npm (reasons why it’s not suitable for client-side are below), but client-side JavaScript until recently didn’t have anything. There were many different package managers (Jam, Component, Volo, Ender), but the majority of them never became popular, and there is little sense in package managers that can’t install the right packages.
Bower is not the standard package manager for client-side JavaScript, but the most popular one: currently there are more than sixteen thousand packages.
Bower doesn’t prescribe to the user its own build system, or to the developer a method of including libraries (AMD, CommonJS, etc.) All Bower does is install the right versions of the packages that the project needs and their dependencies. In other words: it downloads source files for the right libraries and everything they need into a special folder. Everything else is up to the developer.
Why Not npm
The main difference between npm and Bower is the approach for installing package dependencies. npm installs dependencies for each package separately, and as a result makes a big package dependency tree (node_modules/grunt/node_modules/glob/node_modules/...
),
where there could be several version of the same package.
For client-side JavaScript this is unacceptable: you can’t add two
different version for jQuery or any other library to a page. With Bower
each package is installed once (jQuery will always be in the bower_components/jquery
folder, regardless of how many packages depend on it) and in the case
of a dependency conflict, Bower simply won’t install the package
incompatible with one that’s already installed.Installing Bower
To work with Bower you’ll need Node.js and git. Installation:> npm install -g bower
Working with Packages
Let’s try to install something, for example jQuery:> bower install --save jquery # or bower i -S jquery
This command will download the latest version of jQuery into the bower_components/jquery
folder.The
--save
flag tells Bower that it should save the package name and its version into the bower.json
manifest file. In this file is a list of all dependencies of the
project (packages installed with Bower) and other metadata required
for creation of your own packages (more on this at the end of the
article). With the package names it’s possible to specify the version
with which your project is guaranteed to work.We don’t have a file like that yet, which is what the line “No bower.json file to save to, use bower init to create one” in the log is about. Let’s create it:
> bower init
Bower will ask many questions, but until we want to register our
package, answers to most of them don’t matter, you can just press Enter.The question “Set currently installed components as dependencies?” should be answered with “yes”—all previously installed components (in our case it’s jQuery) will be automatically placed in the created JSON file. The question “Would you like to mark this package as private which prevents it from being accidentally published to the registry?” should also be answered “yes”—this will prevent accidental publication of the package into the Bower registry.
Let’s install a few more packages:
> bower install --save social-likes jquery-icheck fotorama
And take a look at what we got:> bower list
bower check-new Checking for new versions of the project dependencies..
bowertest#0.0.0 /Users/admin/bowertest
├─┬ fotorama#4.5.1
│ └── jquery#2.1.0 (2.1.1-beta1 available)
├── jquery#2.1.0 (2.1.1-beta1 available)
├─┬ jquery-icheck#1.0.2
│ └── jquery#2.1.0 (2.1.1-beta1 available)
└─┬ social-likes#3.0.2
└── jquery#2.1.0
The bower list
command shows a list of all installed
packages. Here we see that all packages depend on jQuery, and that Bower
found a version suitable for them all: 2.1.0.In the file system it looks like this:
> tree -L 2
.
├── bower.json
└── bower_components
├── fotorama
├── jquery
├── jquery-icheck
└── social-likes
5 directories, 1 file
Each package is installed into its own folder, there are no nested
packages, and jQuery is only included once. In the project root lies
the created by bower init
file bower.json
, but now it lists all the packages shown by bower list
, not just jQuery.For uninstalling packages the
bower uninstall
command is used:> bower uninstall --save jquery-icheck # Или bower un -S jquery-icheck
You can confidently delete the bower_components
directory or add it to your .gitignore
. The bower install
(without additional parameters) command will return everything to the way it was:> bower install
Deploying the Project
There are two approaches for deploying a project:- Only the manifest file is added to the repo and all packages are installed during deployment. This way there is nothing unnecessary in the repo, but if GitHub crashes during deployment or another server from which packages are installed crashes, there will be problems.
- The
bower_components
folder as well asbower.json
are added to the repository. This way deployment doesn’t depend on external servers, but the repository blows up with hundreds (if not thousands) of extra files.
Semantic Versions (semver)
is,Secondly, it’s a method of describing necessary dependencies, which is used by Bower and npm.
While installing with the
--save
flag, package version are added to bower.json
like ~1.0.1
.
The tilde at the beginning means that during installation version 1.0.1
will be chosen, or a version with a larger last number (PATCH)
if it’s available. This way the installed version will have the latest
bug fixes, but will be fully compatible with the one specified in the
manifest file.Updating Dependencies
Bower has abower update
command, but it updates
packages with respect to the demands of the manifest file. For example,
if it lists jQuery ~2.0.0 Bower can update jQuery to version 2.0.9, but
2.1.0 won’t be installed because it doesn’t satisfy the ~2.0.0 formula.To update packages (and
bower.json
) to the truly latest version you can use the utility. Installation:> npm install -g bower-update
Launch:> bower-update
Searching for Packages
There are two methods for finding packages with Bower: geeky and normal.Geeky:
> bower search jquery
Search results:
jquery git://github.com/jquery/jquery.git
jquery-ui git://github.com/components/jqueryui
...
Normal: open in a browser.Automatic Builds
Bower puts the problem of project builds on the shoulders of the developer. The simplest method is just to concatenate the JS files with Grunt, Gulp or any other task runner that you use.I use Grunt, so I’ll describe how to concatenate the packages with Grunt. There was a on using Grunt in the June issue of last year, so I’ll show my config of the
grunt-contrib-concat
plugin right away:concat: {
main: {
src: [
"bower_components/jquery/jquery.min.js",
"bower_components/fotorama/….js",
"bower_components/jquery-icheck/….js",
"bower_components/social-likes/social-likes.min.js",
"scripts/*.js" // Your site’s scripts
],
dest: "build/scripts.js"
}
}
This method has many downsides: you have to watch the files for each
package, make sure that the files are assembled in the right order
(for example, jQuery has to be higher than scripts depending on it).
The plugincan do this for you: it automatically concatenates all installed dependencies in the right order into a single file:
bower_concat: {
all: {
dest: "build/_bower.js", // Concatenated file
exclude: [ // Packages excluded from Bower
"jquery", // If jQuery is loaded from the Google CDN
"modernizr" // If loading scripts at the end of the page, modernizr should be loaded in the <head>
]
}
},
concat: {
main: {
src: [
"build/_bower.js",
"scripts/*.js" // You site’s scripts
],
dest: "build/scripts.js"
}
}
Registering Your Packages
To make your library available to be installed with Bower it has to be registered. To do this:- at the root of a project there should be a
bower.json
manifest file. - the project should be a git repository (for example on GitHub)
- the project should use semantic versioning and the repository should have a git tag for the latest version
bower init
command is used:> bower init
[?] name: awesomelib
[?] version: 0.0.1
[?] description: My awesome jQuery plugin.
[?] main file: jquery.awesomeplugin
[?] keywords: jquery awesome yay
[?] authors: Artem Sapegin <artem@sapegin.ru>
[?] license: MIT
[?] homepage: https://github.com/sapegn/jquery.awesomeplugin.js
[?] 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: 'awesomelib',
version: '0.0.1',
description: 'My awesome jQuery plugin.',
main: 'jquery.awesomeplugin.js',
keywords: [
'jquery',
'awesome',
'yay'
],
authors: [
'Artem Sapegin <artem@sapegin.ru>'
],
license: 'MIT',
homepage: 'https://github.com/sapegn/jquery.awesomeplugin',
ignore: [
'**/.*',
'node_modules',
'bower_components',
'test',
'tests'
],
"dependencies": {
"jquery": "~2.1.0"
}
}
[?] Looks good? Yes
And, although it’s mandatory to fill in the name
field, other fields are also very useful:description
andkeywords
will help users find your library through the package search interface.main
determines the main file of the package. Thie field can be used by automatic build systems likegrunt-bower-concat
.license
—always specify a license: it tells a potential user of your package whether they can use it in their project. For example, theGPL
license required that every project using it is also released with the same license, which isn’t always possible.ignore
—by default Bower will download the whole repository, which, firstly, will increase installation time, and, secondly, will add unnecessary files to the project. It’s best to exclude everything except the files required for the package to work (main JS file, CSS, etc.), license and README.dependencies
—all packages on which your package depends.
bower.json
file, create a git tag with the latest version and push it to the remote repo:> git add bower.json
> git commit -m "Add bower.json"
> git tag "v0.0.1"
> git push origin --tags
Now you can register your package:> bower register jquery-awesomeplugin git://github.com/sapegin/jquery-awesomeplugin.git
From now on, Bower will check package updates, you just have to create git tags for each new version.To make updating your packages easier you can use tools like https://github.com/vojtajina/grunt-bump or https://github.com/mikaelbr/mversion
from http://frontendbabel.info/articles/bower-why-frontend-package-manager/,
http://blog.sapegin.me/all/bower
相关帖子:http://briteming.blogspot.co.uk/2014/01/bower.html