Hi there! My name is Michał and this is the Softver Tinkerer blog. Here I'm going to write about my ups and downs with software development, mainly frontend JavaScript. Hope you enjoy!

TL;DR

  • WebPack is widely used and very powerful, but it's restricted to static analysis and bundling.
  • SystemJS is future-proof, but it's also niche and requires other tools to achieve what others do.
  • FuseBox is young, opinionated and quite magical, but it's also fast, easy to set up and get going, has lots of features and provides great DX.

Straying Away From WebPack

If you're reading this you've probably done some amount of JavaScript development. You might also know how ridiculous the JS ecosystem has become. There is a vast amount of tools - which is great. The problem is when you have to choose one or the other and the one you chose stops being maintained. Or is completely rewritten under the same name (I'm looking at you, Angular). Or promises a breakthrough with a next major release, which never happens (Gulp). Every one of these choices is a risk. Not so long ago I took a risk by getting rid of WebPack and choosing something else, but this one did pay off so far. This post is both a thank you to FuseBox developers and a stranger telling you why you should use some random library.

Why not Webpack?

In June 2017 I started a new job and for a little while I was researching my options regarding frontend tools. I knew I wanted to use Angular, because it felt familiar having used AngularJS and I also really like TypeScript. I also knew that my only other viable options were React and Vue, but I did not have that much experience with either, so that was not much of a choice. I did not have any strong opinions about setup, so I went with Angular CLI, since it is the officially supported solution. Angular CLI is based on WebPack, but for sake of simplicity the entire config is blackboxed and not accessible for end user (at least it was not so long ago). That didn't bother me, since at that time I was not aware of any special requirements for my project. However when they did come up it turned out I needed to rethink my ideas about WebPack being the ultimate tool for everything. The idea is "simple" - project should allow plugins / mods being added to it and ideally this should be as simple as uploading a file or zip to the server.

Thus, the research began. I already knew that WebPack was the current reigning - it's one of the very few things that the Angular and React communities agree on. That said, my first step was to investigate if you could load a module dynamically in WebPack.

I know that lazy loading is supported, however anything that is meant be lazy loaded needs to be statically analyzed - i.e. be present in filesystem during build. So for my understanding WebPack offers "pseudo-dynamic" imports. It separates some files into a distinct chunk which is loaded via XHRHttpRequest, but the API is hidden from developer. So for this use case I needed some alternative.

Why not SystemJS?

Before Angular went stable the team at Google campaigned for using SystemJS. SystemJS is a module loader, not a build system - it operates at runtime, so given an ECMAScript import:

import {Injectable} from '@angular/core';

an XHRHttpRequest will be performed. It's also worth noticing that it is based on the official module loading specification, which is going to be implemented by browsers at some point in the future (Chrome already has them). That seemed to be a solution to my headache with WebPack, so I tried to incorporate it into my project. The thing is, SystemJS does not play well with npm. The official solution is to use JSPM which handles this, but due to frustration I dropped out before I could get it to work. StealJS, which is built upon SystemJS seems to resolve this and handling non-JS assets, however getting it work was also a pain.
In the end trobules with using node_modules, combining JS with non-JS assets and a bit weird Developer Experience (BYO dev server was REALLY frustrating) made me give up on SystemJS and StealJS.

Why not...?

Other tools I did some research on:

  • Browserify - WebPack predecessor, "NodeJS modules for the browser",
  • Rollup - ES6 modules and tree shaking, great for libraries,
  • Brunch - WebPack with simpler API.

If ANY of these tools support asynchronous import of UNKNOWN code, let me know! I did not see any potential of solving my problems in them, so I haven't done any testing.

Why FuseBox?

I came across FuseBox by accident, searching for dynamic imports in WebPack.

In compliance with es6 proposal-dynamic-import and Typescript 2.4 dynamic imports FuseBox supports import statement.

Great, but my spidey sense was tingling - "it's probably pseudo-dynamic imports like WebPack". It turned out that it does more.

FuseBox provides a powerful runtime API. It is both a module bundler (like WebPack), but also a module loader providing virtual files at runtime.

An interesting solution is that when FuseBox can't find what you are trying to import, as a last resort it tries to load that module via XHRHttpRequest. It also allows to register modules at runtime, so basically you can load any script via Http and seamlessly integrate it to your code. How cool is that?!

FuseBox also came with a few other bonuses:

  • it's REALLY fast - it can recompile a moderate size app within 50-100ms,
  • documentation is at least as good as Webpack's,
  • simple API,
  • seamless npm integration,
  • built-in dev server,
  • Gulp-like task runner Sparky,
  • TypeScript is a first class citizen and requires zero configuration,
  • there are plugins for Angular template loading and lazy loading,
  • Quantum - a code optimizer, something combining minification like UglifyJS and treeshaking like Rollup (incidentally it does NOT work when using runtime imports, so I was not able to use it).

FuseBox is a great tool, in a nutshell it aims to be a more full-featured alternative to WebPack and it succeeds in many aspects. Those are the good parts, read on to find out what I did not like about FuseBox.

Why NOT FuseBox?

Of course FuseBox is not the "One Ring to rule them all". There are some things that could render it unfit for your case. Consider this:

  • FuseBox has just turned one year old (initial GitHub commit - October 2016), so it's not exactly "mature",
  • opinionated API,
  • it does a lot and some of the API is pure witchery,
  • FuseBox provides its own test runner and assertion library - which I don't mind, but there is no built-in support Karma / Jasmine and I needed to come up with a custom solution,
  • documentation is good, but could be better - once or twice I needed to check out the source to know what's going on.

Summary

I really like FuseBox. The only thing that was not smooth to setup was Karma and Jasmine, but I hope that changes in the future. I strongly recommend trying it out for a new project, or even for an existing one, especially if WebPack causes you trouble.

Thanks for reading!