While I was developing the bubble search example and as I am researching Grunt, Bower and their ilk for ASP.NET vNext work, I’ve come to the conclusion that I just don’t know enough about the various components that make up modern web development. In this series of articles I’m going to try and do the “101 level” of Web Development tools. For those non-Americans among us, “101 level” is just the basics – enough to get you started. I’ll start today with package managers.
You need to understand package managers.
Why do you need to know?
- A repository of libraries that you can access. In the old days you had to get someone to tell you what library provided some feature so you could go Google it. Wanted a jQuery compatible Datepicker? Let’s google it. Of course, you then got articles about choosing a datepicker, an article on doing this in ASP.NET without jQuery, forums complaining about the lack of a standard jQuery date picker and so on. Stuff you didn’t want. Pretty much all the package managers nowadays provide some sort of search capability that you can use so you are restricting your search view to just libraries. Then you can focus your research on the ones that sound good.
- Dependency Management. Let’s say your colleague tells you that you want to use Bootstrap. You go and download Bootstrap, stick it in your project and it’s all working. Except it isn’t. Bootstrap has a dependency on jQuery. So you have to go and download that as well. In any substantial project, dependencies like this happen all the time. Even worse is that libraries depend on certain versions of other libraries. A good package manager will handle all these dependencies for you.
- Version Management. Sometimes the API of your favorite library changes and they will bump the major version to indicate that. Sometimes they will just do a revision for bug fixes and they will bump the minor version. You probably want to be able to revise your app so that it includes the latest version that includes the same API as the one you are using. Version Management allows the developer to say “give me the latest 1.x version of the library and all it’s dependencies” – a very good thing when trying to keep up to date with bug fixes.
- Cleaner Source Tree. I don’t have to check in the resources that are available on the Internet. In fact I can explicitly disclude them. This means that I have a cleaner source tree – only my code and none of the code I’m including from the Internet. Most of the time that means that my check-in/check-out/sync process is significantly faster.
Do you need a package manager? I’d have to say no, but it will make your life much easier if you use one. That brings us to our next question.
Ok, so I need a Package Manager. Which one do I choose?
In Linux land there are two package managers – RedHat defines rpm packages and Debian defines deb packages. Everyone else pretty much uses one of these. In Windows land there is OneGet most recently and Chocolatey for everyone else. My point is that there is a standard – it’s a good thing. Web Development – not so much.
If you are living in Microsoft .NET land then you need to know about NuGet. It’s the package manager for the Mirosoft .NET platform and heavily used in Visual Studio development. The short short version is that you have a project.json file that you use to define the packages you want and their versions. When I want to build a project, I do a package restore to pull the assemblies I want to include. That way I don’t have to check in binary libraries into my source code tree. In Visual Studio this is handled for you. If you are using an alternate build method then you can do a nuget restore to restore the packages. The packages are stored in a special packages directory once restored.
The downside of NuGet is its coverage. It’s got great coverage for the Microsoft world, but practically none outside of that world. That means it’s useful – necessary, even – if you are developing ASP.NET applications and probably not the thing you want to use otherwise.
One of the other nice features is that you can codify your build process within the package.json file. This abstracts away your build process – you can just define a build target to “do the right thing” – npm will kick it off for you. This is a major time saver if you have multiple people working on the project or you intend to distribute your project. I’m a big fan of doing things in a way that is obvious to the next guy and this fits.
In terms of packages – 130,000 packages. WOW! This pretty much means everyone who has a need to distribute a library is doing it with npm.
Let’s try a little experiment. To install a package, just use npm search to find it and then npm install. If I run:
npm search bootstrap
I get over 400 entries. Way too much. However, I see there is a bootstrap package – that looks promising. So I install it with this:
npm install bootstrap
It does its thing and a directory node_modules/bootstrap is created. However I don’t have the dependency jquery downloaded as well. I need to ask for that separately. This is only a small problem – it means I have to manage dependencies myself, which is one of the four points of a package manager. (Note to bootstrap package owner: You need to define dependencies!)
Some packages do indeed refer to dependencies. For example, using this command:
npm view grunt dependencies
This shows me the dependencies for a package. I can clearly see that grunt has some dependencies which will be downloaded for me. It’s not so much that dependency management is lacking. It’s that the package authors are somewhat lazy sometimes.
Bower was developed by Twitter for distributing and including client-side libraries. As a result it only deals with client-side libraries. This means that you are going to have to get the tools from someone else. If you use bower, you are likely to be pairing it with npm for tool support. The good piece of this (and perhaps why you may include it) is that it can also distribute HTML files and images and fonts and CSS files – the other stuff that web applications are made of.
Bower is growing, but it’s still small – 18,000 packages. You create a bower.json file in your project, download bower and it’s dependencies using npm and then run a package restore. It places the files in bower_modules so you can do the exclusion from source code control.
One of the nicest things about bower is that a bower package is just a git repository. This meant that you could check in a configuration file to a repository on github.com and then go register your package – immediate publication.
Another good thing is that the dependency mapping is more normally there. Remember our npm task to get bootstrap installed? Bowers package handles the jQuery dependency automatically. However, again, we are relying on the package authors – as the bower ecosystem grows, this may become a problem as well.
The biggest issue with bower is coverage – npm is much much bigger and there seems to be almost 100% overlap between bower and npm, so why not use the package manager that you need to download bower in the first place for your project?
After these three package managers there is a fragmented mess. Here are some of the others that I found while googling and the reason why they are also-rans:
- Component is a vertically integrated frontend development system. It’s not just a package manager but also a build manager and pre-processor. It doesn’t really play well with others, so you have to buy into their way of doing things or use something else. I hate lock-in, so pass on this one.
- Ender seems to be down now, so maybe it’s already dead. Ender was a wrapper for NPM and used the same npm library of packages, but made it easier with authoring tools. I did’t see much point in it as npm was so powerful.
- Jam is another up and comer that focuses on the client-side libraries in much the same way as bower. However, at less than 1000 packages, only expect the mainstream packages to show up there. You will be relying on something else for the remainder.
- Volo is a package manager explicitly for AMD modules. We created an AMD module last week when I was talking about the Bubble Search and RequireJS. Just like bower, Volo uses a Git repository as a publication mechanism. So – good for AMD modules and bad for everything else (and there is a lot in “everything else”).
I was recently asked why I am still on Facebook. Well, the rest of my friends are. The same is true here – why am I keen on npm? Because everything I need is on there.
You need a package manager. Yes, you can do without it but it’s painful. It’s like compiling a major Java project without Maven.
Once you’ve gotten that fact, be aware that you will need 2 package managers – NuGet for your Microsoft .NET development work to download the backend libraries you will need, and NPM for your frontend library needs. You also have to be aware that some packages have dependencies that aren’t listed – bootstrap is a prime example.
You may dip into other package managers for specific circumstances but it’s unlikely. It’s well worth your time learning these two systems, how to configure and run them and what they offer. Fortunately, both sites have excellent documentation, so research is a breeze.