Bower

Bower is about to become the best friend of any Frond End developer! It allow us to easily manage Frond End packages and their dependencies. A little bit like what Composer does with PHP packages.

Bower keeps you focus on what’s really important: The code you create, the added value that you generate from third party librairies. Starting a project then becomes real quick and painless as Bower manages dependencies and put them into a dedicated bower_components folder.

More about Bower…

Bower is a package manager for the web. It offers a generic, unopinionated solution to the problem of front-end package management, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat.http://bower.io/

How to install

In order to install Bower in your machine you will need to have NodeJs and NPM installed. I invite you to install them before going further. Luckily I have written a post about it: How to install Node.js, CoffeeScript, LESS and Uglify-js on Ubuntu

Now you are able to run the following command to install Bower globally:

$ sudo npm install -g bower

Install a package

Using Bower you can install easily the lastest version of a package (and its dependencies) using a single command:

# Using a local or remote package
$ bower install <package>

Example

In this example I want to install the latest version of Bootstrap and its dependency (JQuery).

$ bower install bootstrap

bower bootstrap#*               cached git://github.com/twbs/bootstrap.git#3.0.0
bower bootstrap#*             validate 3.0.0 against git://github.com/twbs/bootstrap.git#*
bower jquery#>= 1.9.0           cached git://github.com/components/jquery.git#2.0.3
bower jquery#>= 1.9.0         validate 2.0.3 against git://github.com/components/jquery.git#>= 1.9.0
bower bootstrap#~3.0.0         install bootstrap #3.0.0
bower jquery#>= 1.9.0          install jquery#2.0.3

bootstrap#3.0.0 bower_components/bootstrap
??? jquery#2.0.3

Here within the bower_components folder Bower created two more folders: bootstrap and jquery.

Install a specific version of a package

# Using a specific version of a package
bower install <package>#<version>

Example

In this example I want to install Bootstrap v2.3.2 (the one just before 3.0.0).

$ bower install bootstrap#2.3.2

bower bootstrap#2.3.2       not-cached git://github.com/twbs/bootstrap.git#2.3.2
bower bootstrap#2.3.2          resolve git://github.com/twbs/bootstrap.git#2.3.2
bower bootstrap#2.3.2         download https://github.com/twbs/bootstrap/archive/v2.3.2.tar.gz
bower bootstrap#2.3.2          extract archive.tar.gz
bower bootstrap#2.3.2         resolved git://github.com/twbs/bootstrap.git#2.3.2
bower jquery#>=1.8.0 <2.1.0     cached git://github.com/components/jquery.git#2.0.3
bower jquery#>=1.8.0 <2.1.0   validate 2.0.3 against git://github.com/components/jquery.git#>=1.8.0 <2.1.0

Install several packages from bower.json

If you want to install several packages at once you will need to create a bower.json file at the root of your project. You can do so by running bower init the result could look like the following file:

{
   "name":"your project name",
   "version":"0.0.0",
   "dependencies":{
      "bootstrap":">= 3.0.0",
      "jquery":">= 1.9.0"
   }
}

Now that you have specified the dependencies you can run the installation:

$ bower install

bower bootstrap#>= 3.0.0        cached git://github.com/twbs/bootstrap.git#3.0.0
bower bootstrap#>= 3.0.0      validate 3.0.0 against git://github.com/twbs/bootstrap.git#>= 3.0.0
bower jquery#>= 1.9.0           cached git://github.com/components/jquery.git#2.0.3
bower jquery#>= 1.9.0         validate 2.0.3 against git://github.com/components/jquery.git#>= 1.9.0
bower bootstrap#>= 3.0.0       install bootstrap#3.0.0
bower jquery#>= 1.9.0          install jquery#2.0.3

How to use packages?

Now that you have installed required packages it is easy to reference them in your HTML.

Example

<script src="bower_components/jquery/jquery.min.js"></script>

How to automatically tag a Git repository using NodeJs, CoffeeScript and Cake

If you have worked in a project that have several developers and several repositories, then you know that tagging can be pretty annoying.

Indeed to tag a repository you need to know two things: The latest version of your application and whether the new version contains bug fixes, new features or things that would break the backward compatibility (If following a Semantic Versioning based on MAJOR.MINOR.PATCH).

The purpose of this tutorial is to be able via a Cakefile to tag a repository using a simple task, without knowing the number of the latest version of your application.

Get this tutorial source code from GitHub

What is a Cakefile?

CoffeeScript includes a (very) simple build system similar to Make and Rake. Naturally, it’s called Cake, and is used for the tasks that build and test the CoffeeScript language itself. Tasks are defined in a file named Cakefile, and can be invoked by running cake [task] from within the directory. To print a list of all the tasks and options, just type cake.

What is Semantic Versioning?

Given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards-compatible manner, and
  • PATCH version when you make backwards-compatible bug fixes.

This is not a new or revolutionary idea, but by giving a name and clear definition of the above concept we ensure that the Software user is aware of your intentions.

Prerequisite

This tutorial requires several prerequisite in order to be completed successfully:

  • NodeJs must be installed
  • CoffeeScript must be installed

If those requirements are not fulfilled yet, I invite you to read a post I wrote: How to install Node.js, CoffeeScript, LESS and Uglify-js on Ubuntu

Let’s get started!

Create the needed files

For this tutorial purpose we need only two files:

Cakefile
Contains the tasks to tag the Git repository and all the logic behind it.
version
Contains the latest version of your application
If you are using Unix a simple mkdir Cakefile version would do. If you are on Windows please note that those files do not have any extension (.something) and therefore you are on our own…

Leave the Cakefile empty for now and add a line containing your application latest version (or 1.0.0) within the version file like this.

Add NodeJs packages

We will only need two NodeJs packages, the File System (fs) to read and write the version file and the Child Process (child_process) to execute command lines for us (e.g: git tag -a v2.0.1). Add the below lines to your Cakefile:

# Required packages
fs      = require 'fs'
{spawn}	= require 'child_process'

Create empty tasks

We want to be able to increase the Major, the Minor or the Patch

###
TASKS
###
task 'tag.major', 'Major tag incrementation', -&gt;

task 'tag.minor', 'Minor tag incrementation', -&gt;

task 'tag.patch', 'Patch tag incrementation', -&gt;

To make sure your new tasks are referenced try to run the cake command:

$ cake
Cakefile defines the following tasks:
cake tag.major            # Major tag incrementation
cake tag.minor            # Minor tag incrementation
cake tag.patch            # Patch tag incrementation

Create the methods

Our Cakefile will need four methods to be able to tag a Git repository:

tag()
The entry point method to tag repository.
run()
Execute commands.
getVersion()
Reads the version saved within the version file.
getIncreasedVersion()
Get the current version via the getVersion method and increase the major, minor or the patch.

run(cmd, args, successCallback)

The run method is pretty generic and allow us to execute wathever command needed via the spawn object. It has three parameters:

cmd
[string] The command, in our case “Git”
args
[array] The arguments, options used with the command.
successCallback
[function] Ran once the command is successfully executed.
run = (cmd, args, successCallback) -&gt;
	# Execute the command
	child = spawn cmd, args

	# Listen to exit event
	child.on 'exit', (code) -&gt;
		# Success
		if !code
			successCallback()

	# Listen to errors
	child.stderr.on 'data', (data) -&gt;
		console.log 'Oups something wrong happened: ' + data

getVersion()

Reads the version saved within the version file via the NodeJs File System. It has no parameter.

# define the version file name
versionFile = 'version'
getVersion = -&gt;
	&quot;#{fs.readFileSync versionFile}&quot;

getIncreasedVersion(label)

Get the current version and increase it. It has only one parameter:

label
[string] Could be: major | minor | patch
getIncreasedVersion = (label) -&gt;
	v = getVersion()
	vSplitted = v.split('.');
	switch label
		when &quot;major&quot;
			vSplitted[0] = parseInt(vSplitted[0]) + 1
			vSplitted[1] = 0
			vSplitted[2] = 0
		when &quot;minor&quot;
			vSplitted[1] = parseInt(vSplitted[1]) + 1
			vSplitted[2] = 0
		when &quot;patch&quot;
			vSplitted[2] = parseInt(vSplitted[2]) + 1
	vSplitted.join('.');

tag(version)

The tag method calls the run() method with the appropriate parameters. It has only one parameter:

version
[string] The version in which you want your Git repository to be tagged.
tag = (version) -&gt;
	run 'git', ['tag', '-a', '-m', &quot;&quot;Version #{version}&quot;&quot;, version], () -&gt;
		# Save the new version within the version file if success
		fs.writeFileSync versionFile, version

Populate tasks

Update the tasks by adding a call to the tag method.

###
TASKS
###
task 'tag.major', 'Major tag incrementation', -&gt;
	tag getIncreasedVersion 'major'

task 'tag.minor', 'Minor tag incrementation', -&gt;
	tag getIncreasedVersion 'minor'

task 'tag.patch', 'Patch tag incrementation', -&gt;
	tag getIncreasedVersion 'patch'

Make a release!

Everything is now ready to execute our tasks. Let’s try shall we!

Release a Patch

$ cake tag.patch
Increasing from 1.0.0 to 1.0.1...
command used: git tag -a -m &quot;Version 1.0.1&quot; 1.0.1

Release a Minor

$ cake tag.minor
Increasing from 1.0.1 to 1.1.0...
command used: git tag -a -m &quot;Version 1.1.0&quot; 1.1.0

Release a Major

$ cake tag.major
Increasing from 1.1.0 to 2.0.0...
command used: git tag -a -m &quot;Version 2.0.0&quot; 2.0.0

In a next post I will continue working with this Cakefile and explain how to make a complete release of code (Minification, Packaging and Tagging). This tutorial is now finished, let me know if you liked it or not by commenting 🙂

Get this tutorial source code from GitHub

Sources

How to install Node.js, CoffeeScript, LESS and Uglify-js on Ubuntu

Node.js Evented I/O for V8 javascript

Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

Node.js allow basically to run server side JavaScript.

Installation

sudo apt-get update
# python-software-properties is needed to use add-apt-repository
sudo apt-get install python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get install nodejs

Experimenting

Node.js interpreter is available using nodejs -i

nodejs -i
> var foo = 'bar'
> console.log(foo)
bar

For convenience and because dependencies may use node command instead of nodejs, a symbolic link is necessary to avoid having this error:

/usr/bin/env: node: No such file or directory

Add Node symbolic link

sudo ln -s /usr/bin/nodejs /usr/bin/node

NPM Node Packaged Modules

NPM is Node.js package manager. We will use it to install CoffeeScript, Less and Uglify-js during this tutorial.

Installation

sudo apt-get install npm

Basic commands

# Any package can be installed by using
npm install
# Display the package list globally installed
npm list -g

CoffeeScript Little language that compiles into JavaScript

The CoffeeScript compiler is itself written in CoffeeScript, using the Jison parser generator. The command-line version of coffee is available as a Node.js utility. The core compiler however, does not depend on Node, and can be run in any JavaScript environment, or in the browser.

CoffeeScript simplify the way to create great JavaScript code.

Installation

Leave off the -g if you don’t wish to install globally.

# -g specify that you want to install it globally 
# (otherwise it will install it within a local node_modules folder)
sudo npm install -g coffee-script
npm http GET https://registry.npmjs.org/coffee-script
npm http 304 https://registry.npmjs.org/coffee-script
/usr/bin/coffee -> /usr/lib/node_modules/coffee-script/bin/coffee
/usr/bin/cake -> /usr/lib/node_modules/coffee-script/bin/cake
coffee-script@1.6.2 /usr/lib/node_modules/coffee-script

Experimenting

CoffeeScript interpreter is available using coffee -i

coffee -i
coffee> foo = 'bar'
coffee> console.log foo
bar

LESS The dynamic stylesheet language

LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. LESS runs on both the server-side (with Node.js and Rhino) or client-side (modern browsers only).

Installation

sudo npm install -g less
npm http GET https://registry.npmjs.org/ycssmin
npm http 200 https://registry.npmjs.org/ycssmin
npm http GET https://registry.npmjs.org/ycssmin/-/ycssmin-1.0.1.tgz
npm http 200 https://registry.npmjs.org/ycssmin/-/ycssmin-1.0.1.tgz
/usr/bin/lessc -> /usr/lib/node_modules/less/bin/lessc
less@1.3.3 /usr/lib/node_modules/less

Experimenting

Less does not have an interpreter. To test it we will create a LESS file and compile it into CSS.

echo "@foo: 25px; #foobar{font-size: @foo};" > style.less 
sudo lessc ./style.less ./style.css
cat style.css 
#foobar {
  font-size: 25px;
}

Uglify-js JavaScript minification

UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit.

Installation

sudo npm install -g uglify-js
npm http GET https://registry.npmjs.org/uglify-js
npm http 304 https://registry.npmjs.org/uglify-js
npm http GET https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.4.tgz
npm http 200 https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.4.tgz
npm http GET https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/source-map
npm http 200 https://registry.npmjs.org/optimist
npm http GET https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
npm http 200 https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz
npm http 200 https://registry.npmjs.org/source-map
npm http GET https://registry.npmjs.org/source-map/-/source-map-0.1.22.tgz
npm http 200 https://registry.npmjs.org/source-map/-/source-map-0.1.22.tgz
npm http 200 https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/async/-/async-0.2.8.tgz
npm http 200 https://registry.npmjs.org/async/-/async-0.2.8.tgz
npm http GET https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/amdefine
npm http 200 https://registry.npmjs.org/amdefine
npm http GET https://registry.npmjs.org/amdefine/-/amdefine-0.0.5.tgz
npm http 200 https://registry.npmjs.org/wordwrap
npm http GET https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
npm http 200 https://registry.npmjs.org/amdefine/-/amdefine-0.0.5.tgz
npm http 200 https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz
/usr/bin/uglifyjs -> /usr/lib/node_modules/uglify-js/bin/uglifyjs

Experimenting

Uglify-js does not have an interpreter. To test it we will create a .js file and create a minified version .min.js from it.

touch test.js
echo "var foo = function(prefix){return prefix + ' World'}; console.log(foo('Hello'));" > test.js
# Make sure your code works
node test.js 
# it works!
Hello World
# creates the test.min.js from test.js
# -m, --mangle   :Mangle names/pass mangler options.
# -c, --compress :Enable compressor/pass compressor options.
uglifyjs test.js -mc -o test.min.js
node test.min.js
# it still works!
Hello World
# Display test.min.js content to check out the result of the minification
cat test.min.js
# The compression is not too obvious but
# it removed spaces and renamed the prefix variable
var foo=function(o){return o+" World"};console.log(foo("Hello"));