Life on the front-end side of the development tracks can be an exercise in patience and learning endurance. When it comes to front-end package managers, there is definitely no lack of choices.
In this article I will be focusing on two of the hottest front-end tools: JSPM and Webpack. With Jspm coming to providence thanks to Angular 2 and Aurelia and Webpack being the preference of a large number of React developers.
I have decided to leave Browserify out of this as I believe it has been covered enough and sadly in my opinion, the future currently doesn’t have a place in its heart for Browserify, at least not for me and many others I know who use other tools.
Preamble: this article will be focusing on the usage of Jspm and Webpack on the client-side only.
What is JSPM?
To quote the JSPM site itself, JSPM is “Frictionless browser package management”
It isn’t just another package manager, it aims to be THE package manager of the front-end. You could argue that Npm is already both the front and back-end package manager and that solutions like Jspm are unnecessary.
It is built on-top of System.js which is an ES6 module loader polyfill (which was created by the same developer) which in itself is based on the es6-module loader and underlying official web specification for client-side module loading.
System.js allows us to load modules/files using a plethora of different syntaxes to accommodate to all preferences; CommonJS (Node.js modules), AMD (RequireJS specification) and ECMAScript modules.
While the package management and System.js functionality is great, Jspm also offers bundling as well.
So not only can we manage all of our front-end dependencies using Jspm regardless of where they came from, we can also bundle them all up a variety of different ways; self executing bundles, single bundles and multiple bundles all management by a mapped tree in the config.js allowing for intelligent code splitting and loading in our applications.
Think of it as Npm on steroids plus a loader and a heap of plugins for transforming different file sources.
What is Webpack?
Webpack is a module loader and bundler akin to solutions like Browserify. It actually offers almost everything that Jspm does except it is not a package manager. All Webpack cares about is working with files and bundles, it does not care if you use Npm or if you don’t. It leaves that part up to you. Feed it files and when it matches a particular loader you have specified, it will convert it, copy it or do whatever you want it to do.
There are numerous plugins out there for Webpack that take it from being just a code bundler to something more. The ability to parse CoffeeScript, parse and base64 encode images, include static assets like CSS and use Node modules on the client side is pretty awesome. While Jspm itself can do some of these things, Webpack is more pure in what it is designed to do.
Webpack is a highly configurable code bundler that can handle pretty much sort of front-end code and asset there is. It requires a little configuration to get things happening and you don’t get that out-of-the-box auto updating of your manifest file (like Jspm does with config.js).
As support for HTTP/2 grows, solutions like Jspm are very appealing. At its core, Jspm is designed with HTTP/2 support in mind and some bundling support thrown in as a stop gap until support is a bit better.
When you strip away the package management exterior of Jspm, what you are left with is an intelligent module loader that requires almost no configuration and puts it in the same court as Webpack, but in my opinion has less complexity.
While Jspm still requires the installation of plugins to work with different file formats (as does Webpack), its straightforward approach to dependency management and bundling definitely bolsters the claim of being frictionless package management.
When deciding to use Jspm you have to assess the tradeoffs. Is the thought of another package manager with its own set of commands, modules folder and separate configuration bloated to you? If you are just wanting to work with the one
node_modules folder and use Npm dependencies, then Jspm might seem a little counterintuitive to you.
Since writing the original comparison, Jspm 0.17 is almost ready for the prime time. In .17, Jspm gets a heap of competing features that Webpack has including tree-shaking and hot module swapping. This definitely closes the gap, although in my experience so far, Jspm has a few performance issues to work out before it is as fast as Webpack.
While Webpack might seem like the new kid on the block and darling of the ReactJS world, it is very much as simple as it gets out-of-the-box and grows in complexity depending on what plugins and loaders you use with it.
If the thought of needing to write a bit of configuration does not scare you, then in my opinion, Webpack is the most powerful choice out there. It has loaders for any file format you can think of, it also works on both the client and server-side. When you work with Webpack, you are working with Node modules most likely and it supports them out-of-the-box.
Then there is hot module swapping. This is the killer feature of Webpack in my opinion and many React developers would be inclined to agree. But as I mentioned above, Jspm 0.17 introduces the same hot module swapping concept, so this isn’t really just a Webpack specific killer feature anymore.
Essentially instead of the page completely reloading (thus losing state) only the portion of the code that is changed is reloaded. This means you get lightning fast development and your changes are instantly reflected without losing any of your temporary state data (great for React in particular, but also for all front-end projects).
Having said that, the power of Webpack is pretty unrivalled. The issue with Jspm is if support for something is not there out of the box and a plugin hasn’t been created, you are in the same boat as Webpack. In the case of Webpack there are plugins to do 99% of tasks you would want to do on the front-end. The configuration aspect is where Webpack lets itself down, so if time is important to you and your needs are basic, Jspm will save you a lot of time (mapping is handled automatically in config.js for example).
While Jspm might not be seen as important now in the face of existing tools, when HTTP/2 and its handy multiplexing is more widely supported, tools like JSPM are going to be at the forefront of package and dependency management in the long run as hacks like minification and bundling soon become unnecessary in an attempt to make our web applications faster.
In my experience System.js has some serious performance issues, as does Jspm itself. Currently Jspm feels too unstable, things are changing quickly and breaking. In comparison, Webpack has been very stable and although Webpack 2 will introduce new support and concepts, it won’t be a massive breaking release.
If I were to choose a tool today, I would pick Webpack because of how configurable it is, the plugin ecosystem and direction it is heading. Jspm is great and all, but Webpack feels like you get true power and control.