I’ve spoken about package management in the client side JavaScript sphere before. I’ve extoled the virtues of component and broadly avoid mentioning browserify. A lot has happened since then though. Both have shiny new websites and browserify has hit version 2.
Browserify v1 has been around for a long time. It has an almost magical ability to take JavaScript code that was written to run on a server using node.js and make it work on the client. That’s exactly the issue though. It was a magical black box that seemed to do more and be more complex each time you looked at it. For a long time it was plagued with bugs when running on windows. It attempted to do all the things that should be seperate extensions internally in the one module.
Doing too much is a problem. If I rely on something I have no understanding of and it ceaces to exist, I’m completely stuck. Component, by contrast, is fantastically simple. You list where all the JavaScript files are and then it concatenates them into one long file with the standard require logic wrapped around them. It couldn’t be simpler.
This simplicity made it easy to extend. I was able to build a streaming version and a website which serves up fully compiled modules with ease. It was always easy to see what was going on and to debug.
Browserify v2 is made up of a collection of small modules. Each module is inherently streaming, which is perfect for building things like a website to let people download pre-compiled modules. All browserify does is handle the require side of things. It detects calls to require so it knows which files are needed, and then it concatenates them into one long file with the appropriate thin require logic wrappped around them.
It has clever fallback logic when it doesn’t find a module so that you can include multiple bundles where some bundles can depend on things in bundles which were loaded earlier. This means that browserify can make excellent use of CDNs and caching.
When creating a module, the main downside to component is fairly obvious. For every JavaScript file you create you have to add an entry to scripts in component.json. The other downside is that if you’re writing for both server side and client side you have to add both component.json and package.json with broadly very similar contents.
Both component and browserify allow you to support different code for client and server. Component does this by having an entirely seperate module definition file with its own main field. Browserify does it by adding a simple "browser" field wich overrides "main" when in the browser.
When publishing a module the main issue is finding a name for it. Component uses GitHub as it’s registry while browserify uses npm. npm has a flat namespace and you can name modules anything you want.
To publish you run:
npm publishTo install you run:
npm install my-moduleAnd then in your code you load it using:
var mod = require('my-module');This is great, providing nobody already has ‘my-module’ as a name. Having said that, if they do there are two ways it can still end well:
By contrast, GitHub enforces a strict two-tier namespace. The first level is your username and the second is your module name. You’re guaranteed to be able to get any module name you want, but you have to prefix it with your username.
To publish, just push to GitHub
To install you run:
component install ForbesLindesay/my-moduleAnd then in your code you load it using:
var mod = require('my-module');Notice that the username prefix is dropped once it’s installed. This works really well. It’s worth noting that you can still get this behaviour using npm. You can use npm to install anything from a GitHub repository providing it has a package.json file. If the package.json file has a name property set to my-module you can still do:
npm install ForbesLindesay/my-moduleAnd then in your code you load it using:
var mod = require('my-module');So in essence, npm is just as magic, but has the advantage of working for server side code as well
One of the hardest thing with any new module system is finding the modules that do what you need them to. Ultimately many people just end up searching GitHub using Google. Once most people converge on one module system, this will likely become an acceptable solution, but at the moment it’s completely inadequate. Most of the libraries you will find will not work with your chosen package manager.
Both browserify and component do come with a dedicated search system. Neither come up to scratch though. Component’s is a new website, it’s very shiny, but doesn’t give you any information about the browser compatibility or quality of the components. It has a search in the bottom left corner, which is just a basic text based search. It’s difficult to browse through and for the moment I still prefer the old site at https://component.jit.su/ which at least makes the licence very clear and categorises the modules.
Browserify’s is initially just a blank page with a search box, somewhat un-inspiring as a starting point. when you start typing you get a simple list of modules and descriptions. This works fairly well but again lacks info on licenses. It does show test results for browser compatability when available from http://ci.testling.com and I’d really like to talk to them at some point about adding support for https://jepso-ci.com
What both of them currently seem to lack is any sense of the fun that can be had browsing really cool modules by category. There are awesome things out there, and sometimes seeing something you hadn’t thought of can spark and idea for something else that would be cool to build.
Disclaimer I built https://jepso-ci.com so I’m biased
It’s curicial when your writing code for the browser that you have unit tests which can be automatically run across all the browsers you want to support. https://jepso-ci.com can run any tests that will run in a real web-browser so it’s great for testing both component and browserify based code. At the moment jepso-ci does not have support for automating the build step for browserify, but this will be comming soon. You can track the progress in this issue
http://ci.testling.com is currently the only other major cross browser continuous integration platform. It’s built by the same people who built browserify, so naturally the two work well together. It has no support for easilly running the same tests in a real local web browser though, and doesn’t seem to provide any information about the html of the page the tests will be run on.
Component aims to view modules as more than just JavaScript (hence the name) and includes CSS and other files. In the long term this is definitely something the world will need. There’s a difficulty for now though in that CSS doesn’t have any nice systems for modularity. It’s one global namespace and it’s really ugly. It has no variables, no parameters, no opportunities for configuration. As such I would suggest that component’s CSS support is essentially degenerate and insufficient.
Browserify views modules exactly like server side JavaScript does. They’re some JavaScript code, joined together with require calls. You can easilly add a build step that converts a text file into JavaScript, and CSS just isn’t ready for a package manager yet anyway.