FuseBox 2.0 — The beast reborn

Feras Khoursheed
fusebox
Published in
10 min readMay 10, 2017

It has been 6 months since we made Our first release of FuseBox — it has been an amazing journey, and this is the next step! We got so much feedback, followers and amazing new people contributing to our baby.

We’ve been expanding rapidly, adding more seeds & examples, rapidly completing GitHub issues, reviewing the ever-growing contributions of the community. Our Gitter Channel members are growing daily, and are a source of motivation for us to achieve such a huge task! But it did not stop there! We have been contacted by big names in the industry (which we will reveal soon with their consent) who asked us for custom implementations, and we did it.

Everyone praised the simplicity and speed of FuseBox, some even told us that FuseBox is a life saver. All of this made us more determined to continue our mission. We knew we had to work more, but this was not enough. We had to swim faster and flex our muscles harder to please the crowds. Therefore we decided to work on the next milestone of FuseBox, Version 2.0 😊.

The beast reborn

Working on a major product version is not an easy task. Many things need to be taken into consideration. Things like breaking changes, new features, backward compatibility, etc. But what is more challenging, is listening and implementing users’ requirements. We made it a point since day one that FuseBox is a product by developers for developers. That is why we want every new change to FuseBox to stay true to that motto, so we literally worked relentlessly day and night to get it done😊.

What is new? Well lots, but aside of the bug fixes, let us list the major changes before we delve into details for each one of them.

  • Improved performance.
  • New Configuration API.
  • Chainable API.
  • Code splitting.
  • Arithmetic Symbols.
  • Hashing.
  • Separation of HMR & watching.
  • New cache engine.
  • Rollup plugin.
  • New plugins.
  • Sparky Task Runner.
  • Test Runner.
  • Brand new documentation.

Improved performance

One of the main traits of FuseBox is that it is freaking Fast! And we had benchmarks to back this up since the start. But if we can improve it more, then why not 😊. We reworked many of the internals and ran extensive tests and analysis. The result? FuseBox is now twice as fast as it was before (in some cases it much more). yeah, you heard it correctly! The need for speed is in our DNA. Check it out here

New Configuration API

FuseBox 1.0 API was simple, clean and got the job done with the least amount of code. But with all the new requests by users and new enhancements and features introduced in version 2.0, it was due for a face-lift. We now have the concept of producer. A producer is a master configuration that retains a context, plugins and other settings. The benefit of this is that you can apply a universal configuration to as many bundles as you want to create (write once, use everywhere). See the example below:

That’s it. With fuse.run() command above, FuseBox will start bundling for you.

Chainable API

Continuing on our new API upgrade, we added the ability to chain config for each bundle. This allows for a simpler and cleaner way of defining your bundle config without the noise associated with typical configuration style. It is important to mention that FuseBox is smart enough to override any universal configuration when you define it per bundle with the chainable API. Below is an example that shows how you can disable sourceMaps for a server bundle:

Code Splitting

This was one of the most requested features by the community. We kept getting hammered about how it is needed. It is fair to say that we realized this since we started working on FuseBox, but we were saving it as a kind of Christmas gift for those who bought in into the world of FuseBox 🎄🎁

Now code splitting is one heck of a complicated feature, it requires all the internals of FuseBox to understand it, not only that, we must provide a simple and sensible configuration and API to use it.

For those of you who never dealt with code splitting, the idea is really simple. You tell your bundler to split your one mega bundle into many smaller ones, but why? Well, it is all about performance. If you are doing SPA then you most probably won’t need to load all your Application code at the start. You would want to load the code only when the user needs it. This is not limited to SPA websites, it also extends to traditional websites.

Code splitting with FuseBox is really simple, the process is as follows:
• Create your master bundle, FuseBox will be smart about splitting it.
• Create your shared configuration.
• Set your bundling arithmetic.

FuseBox will do the magic internally, it will create a manifest of your bundles and solve them for you at run-time. The whole process is automated as much as possible.

To give you a taste of how simple it is to setup, check the below example:

We decided to split our code based on routes, which means that FuseBox will create the following bundles for you: app.js, about.js and contact.js

As we mentioned earlier, this is not enough. We need to use those beautiful babies. And guess what, this is how you do it:

Yep that’s all it takes to split and use your code 😊.

See the full examples for code splitting, code splitting with react and code splitting with vendors.

Arithmetic Symbols

It is much cleaner now. We added extra symbols to handle more complicated scenarios. You can program it the way you want. You can tell it to bundle everything to one file, extract dependencies, exclude packages, etc. It is really very powerful. We urge you to look at the documentation to get more acquainted with it.

Hashing

Hashing is important for managing releases. It allows us to invalidate the browser cache when serving a new version of our Application. We designed FuseBox hashing to be as simple as possible. We also did not forget to integrate it with the whole pipeline to produce the correct required results. It is highly customizable and you can select from one of the many algorithms we provide to suit your taste.

Separation of HMR & watching

FuseBox had those since the start. But people gave us great feedback about the diversity of their scenarios. The most important lesson here is that what you want to use HMR for, does not necessarily need to be watched by FuseBox bundling process. So, we realized that they had to be separated to tackle this and other scenarios correctly.

Speaking of HMR, it is awesome now 😎. For those who don’t know what it does, think of it simply the same as browsersync when you use it to refresh your browser automatically on any file change. But with FuseBox HMR, we won’t make you refresh the browser, we will automagically reload only the files that changed, and all of your changes will immediately appear on your page!

If you have two monitors, try to set your editor in one and your browser in the another, then change your code, boom! You will see changes immediately in your browser without a refresh! Did we mention that HMR works with all FuseBox plugins and files? This means that it works with SASS, Less and HTML files, basically anything you feed to the bundle. So you are not limited to JavaScript code only!

Suffice to say, FuseBox HMR will work out of the box in most scenarios, but for those scenarios where you need to do some custom logic when a file change, We got you covered. A very good use case is how to keep your component’s state when you are using React. Mr. Basarat has a great article on that.

New cache engine

One of FuseBox’s most great features, it is the secret sauce to how FuseBox feels like a Lamborghini — in no small part thanks to our caching. it worked correctly and delivered on the promise, but users reported some issues on Windows OS, in addition to some race conditions. So, we refactored the entire thing! Caching in FuseBox is not simple, many factors need to be considered, we need to track what changed and what did not, we need to work with the complexity of npm packages and their dependencies. We can tell you it is not for the faint-hearted. We worked really hard on this one to make it more stable and faster. The result is really a smooth experience. Go give it a spin 😊.

Rollup plugin

This is really funny. You would say, Why would I use a bundler in another bundler? Because FuseBox is awesome 😊. Aside of that, we have mentioned earlier that we have been approached by big names in the industry for custom implementations, and rollup was one of them. For those who don’t know rollup, it is bundler focused on bundling es6 code. It is awesome and it has a feature FuseBox does not have yet! that is tree shaking. Tree shaking, allows you to only bundle what you use, so imagine you have this awesome huge lib, and you are using only one function from it, tree shaking will bundle only this function for you, thus smaller bundle size.

The party that approached us had an already complicated setup done with rollup and other custom tools. But they tried FuseBox, felt the power and loved it. But rollup does not have many of the features FuseBox offers. So, they asked us if it is possible to combine the power of both, and we did.

Then we thought, hey if this is working, why not make it a plugin and let everyone else enjoy it and maybe throw some love at us one day.

New Plugins

We can’t release a new version without some plugins love. Besides, people asked for them, so we were more than happy to make them! Below are some of the new plugins we introduced in version 2.0 and we are cooking more as we speak, not to mention third party plugins being developed by our beloved users.

  • CSSModules Plugin
    allows you to include stylesheets as a key-value map of the class name in your file to the transformed value.
  • Copy Plugin
    If you are coming from webpack you already know this, but if you are not, the plugin allows you to copy your files to a destination folder and return a hashed URL when required in your code. If no options are specified, the plugin copies your files into assets folder.
  • CSSResource Plugin
    An awesome plugin that allows you to package and copy your CSS resources like images and fonts, rewrite their paths and some cool macros to customize your resources paths.
  • WebIndexPlugin
    Generates an HTML file once a producer’s job is completed with the ability to customize the template.

FuseBox Test Runner

Well, this one should have a post of its own… Essentially, we were doing our unit tests with mocha and it is fine, but it was slow, and we had to do extra wiring to write our tests with typescript. Then, it occurred to us, if we already have a great engine, why not create our own test runner? It may sound crazy, but when we started working on it, we realized it is possible.

Now, why would you use FuseBox test runner instead of mocha for example? Well, plenty. First, it is built on top of the same engine Fusebox uses for bundling, this means that it benefits from everything FuseBox has, speed, caching, plugins, etc. Secondly, it uses Typescript by default. This means you don’t have to wire anything, it just works. Check the example below to see how clean and simple the syntax is:

Thirdly, it has built-in chainable assertion API. It has a customizable reporter to cover all your reporting needs. To sum it up, if you install FuseBox, you already get the Test Runner as a bonus and you keep the same workflow and conventions you use with FuseBox.

Sparky Task Runner

Again, this one should have a post of its own. Fusebox is bundler, it deals solely with analyzing and bundling your code. But when you create a project this is not enough, you often need to do typical tasks like copying files, logging, etc. And so, Sparky was born. Sparky is just like gulp or Grunt, the difference here, is that it is built on top of FuseBox engine. So, you get all the goodies included — it can even use FuseBox Plugins!

Now we did not want to create a complicated task runner, as FuseBox already doing much of the lifting, so we just included the essential functionalities for daily requirements, and it is up to you to plug in what you want. It is worth mentioning that Sparky is Asynchronous so you get the ultimate performance. Sparky also allows you to run tasks in parallel or sequentially.

Documentation

Our old documentation was… not so good. With that in mind, we revamped the entire documentation system! We created our own documentation server. The result is a beautifully structured content. We added search and more code examples. We think that you are going to enjoy it.

We live and breathe FuseBox, we use it in our work on daily basis, it is running major websites. So, it is not a hobby or a side project, it is an integral part of our career. We are just at the beginning of this journey and more goodies are coming. We still have some tricks and surprises up our sleeves. We are dead serious about this and we are formulating plans to offer official support and other business possibilities. We are embarked on a mission to deliver one of the best tools in the industry.

Summary

Last but not least please visit our 🔗 website and join our 🔗 Gitter channel . We need you, FuseBox won’t exist or thrive without your support and love. Thank you to all of you who graced us with their ideas, PRs, and those of you who had the patience to argue and fight with us to convince us with their requirements.

Until the next post, enjoy fusing some awesome products 👋

--

--