Thursday, January 30, 2014

Using Bower as the Package Management tool for Internal, Private Libraries

This article is relevant for: 
- Grunt version 1.2.4
- Bower version 1.2.4
it may or may not work for other versions.


bower.io is great! and if you already use it for Package Management then you know why.

I'm currently the HTML5 Architect here at Foxtel and we are launching a new HTML5 platform for apps to run on our next generation Set Up Boxes. To prepare for this I'm building a Foxtel App SDK which will be the starting point for vendors and app developers to get their apps onto our platform.

Internally here, we are also launching Foxtel.js, which is the common helper library for all our apps. As development work on Foxtel.js is actively happening we have new versions coming up weekly. Some of these versions are not backward compatible and therefore we needed a good package management solution for apps that being build using the App SDK.

Enter Bower.

I've been using it for many months now as the Package Management solution for my open source frameworks HTML5 Skeletor  and HTML5 Thor where common libraries like jQuery and YepNope are fetched and installed via a Grunt Task. But I needed a way that I can also use it in our SDK to fetch and install specific versions of our Private and internal Foxtel.js library.

Most people think that Bower is only for Public Git Repo based code but if you read their documentation it mentions that you can point to private Git Repos as well. I was not able to find any good resources online on how to achieve this so I worked it out myself today.

Here are the steps on how to use Bower for Private Package distribution.


Step 1:
You will probably have a internal Git server that hosts your private libraries. Get the Repo URL for the private library repo that you want to use Bower to pull into other apps.


Your Repo can also use Git "Tags" to define "Versions" of your library (e.g. 1.0.0, 2.0.0 etc). I've been practicing this for all my projects as I'm sure lots of other developers are too. If you have Tag based versions, Bower let's you specifically target the Tagged Version you need and download at that specific commit. That's pretty cool and useful :)

Here are the Tags I am currently using (Most were just for testing) as an example, later we will see how we use Bower to target these tags specifically:



Step 2:
Open the App you want to include the private library (This is assuming you are already using Bower on your system and/or you are using Bower as part of a Grunt workflow - if you want to see how this works you can try HTML5 Skeletor as it includes this workflow).

Open the "Bower.json" file (Which is the meta file for Bower that you use to define your dependencies). It would look something like this:




This file tells the Bower core that your apps needs jQuery, modenizr and yepnope and also those approximate versions of those files.

Step 3:
Now if you open "Terminal" (or another Command Line tool) and type -
bower Install 

You will see output like so:



And you will then see the libraries installed in your apps folder like so:



Step 4:
Now, let's extend this and add our private library as well to be fetched by Bower.

In your Terminal again, and type -
bower install foxtel.js=git@privateip.com:paulm/foxtel-js.git#~0.0.2 --save

What we are doing here is telling Bower that our app now has a dependency on this Private Library called "foxtel.js" which is located in our private Git Repo "git@privateip.com:paulm/foxtel-js.git". By adding the "#~0.0.2" at the end of the Repo location we are saying that we are specifically after the Tagged Version 0.0.2. Finally the "--save" is to automatically add this dependency information into our bower,json file like so.



* Using ~0.0.2 as above actually could lead you to see some usual behaviour, I believe ~ means closest match to the version specified so sometime you will get the latest version even if you wanted an older version. To get around this use #0.0.2 to target that version specifically. 

Now if you repeat Step 3 an type -
bower install

You will notice that Bower has fetched the specific version of your Private Library and installed in your app.



As you can see this works and we can use Bower in our internal networks to share Private Libraries and control version distribution.


Additional Required Step:
As mentioned above you can use Bower to target Tagged Versions of your Libraries, for this to work you also need to include a "bower.json" as part of that project as well in order to provide the meta data Bower needs to work our version targeting in the backend.

You can create this file automatically by running the following in Terminal (You will be presented with some command line options in the form of questions by Bower) -
bower init

Or you can create this manually and have a file similar to this:


The most important thing here is to keep the "version" property up to date to match the Tagged Version you are using when you are checking your app into Git.


Issues:
I've noticed that sometimes its not very stable when you care trying to get specific version of your private libraries. In this case I run -
bower cache clean
to flush the cache and then try which results in more stability.


Conclusion:
Package Management is one of the most useful helper features for frameworks and SDKs and Bower is my favourite plugin for this. With the above steps you can take this further and implement Private package management as well to be used internally in your company for private library and source distribution.

Hope you found this helpful and as always shoot me some comments if you have any questions or suggestions.





5 comments:

  1. For an easier private bower package management you could use:
    https://github.com/Hacklone/private-bower

    It's extremely easy to use and you won't have to register your private package to the public repository.

    ReplyDelete
  2. For an easier private package management you could use private-bower https://github.com/Hacklone/private-bower
    With this you won't have to register your private package to the public bower registry

    ReplyDelete

Fork me on GitHub