Muban

A backend-agnostic framework for server-rendered HTML using a modern development setup.

Backend agnostic

Muban doesn't care what backend system you use, it uses Handlebars to render everything on the client when developing.

Never be slowed down by waiting on backend setup and integration, use mock data to preview all your components.

Component based

Create small reusable components by keeping the template, style and script together, and compose them to build blocks that make up your site.

When the HTML is rendered on the server, Muban will attach components to the DOM and manage interaction between them.

Webpack

Muban makes use of a common webpack setup, enhanced with custom loaders to even support hot reloading for your Handlebars templates.

You're free to adjust the webpack setup to your own liking to better suit your personal preference.

Dynamic data

Traditionally, server rendered websites only rendered on the server, and each action would require a page load. SPAs do the opposite, they render completely on the client without ever needing a page load. They communicate strictly with API using fetch.

Wouldn't it be nice if there was a middle ground? Quickly load pages from the server, but also use fetch on highly dynamic pages, like auto-suggest searches or applying filters to search results. Depending on the backend, data can be returned as HTML (reusing the same rendering as the original page) or as JSON.

When the server returns HTML, you can just replace a certain section of the page. But don't forget to re-initialize all the components that exists within that HTML. Muban supplies utils to make that process painless.

When working with JSON, you'll have to replace data in already rendered HTML, without a template engine like Vue or React. Muban makes use of the special created html-extract-data module where you can extract and convert any data from any html structure. Muban implements and describes best practices when working with existing HTML.

When working whit extracted or new data, sometimes you wish you had some sort of template language. Most template languages cannot be used, because they either require client-side rendering, or only work on string-based templates. We found Knockout to be a perfect candidate, since it allows you to define HTML-bindings from JavaScript. This means you never have to update your HTML when adding complex template logic. Muban adds some utils to convert rendered HTML to interactive templates. It's completely optional, but will add some additional bytes to your JS bundle, so use only when needed!

With knockout already available, it's super easy to make a small part of your site that doesn't have to render on the server, interactive on the client. Muban provides custom webpack loaders that allows the same setup for both Muban and Knockout components. It even allows for integration with Redux if there is the need to communicate state between components.

Animation

Not every site will need the same level of animation. Information focused sites would benefit from small details, like smooth hovers. But if your website is more focused towards creating an experience for the user, you might want to transition in components when you scroll the page, create parallax effects, or manipulate the page in such a way that it just looks like a SPAs.

Having a component-based setup that allows communication through the framework helps to create a foundation for setting up high level transitions and animations. Create animation timelines in your components that are automatically picked up when entering the viewport.

Vision

It's hard to explain exactly what Muban is. It's not just a framework or library, and it's more than a boilerplate. Muban is how we envision the frontend development workflow when building server-rendered websites. It's a combination of a small runtime framework, a custom but adjustable webpack setup, and a set of tools to allow a efficient way of working.

Traditionally those websites were made by including some scripts and styles, and writing javascript in a single file using a lot of jQuery plugins. A lot has changed since then, where most of the innovation has happened around Single Page Applications.

With the rise of webpack we got used to code with hot reloading, and it's hard to live without it. The choice to bring HTML rendering to the client makes it possible to hot reload everything; your scripts, styles and templates! We want to make use of Babel or Typescript to write modern JavaScript, and we can compress and combine our code better than any server side framework can.

Another aspect that became popular with SPA frameworks is to make everything a component, and make that component reusable. Muban tries to embrace that philosophy by importing your script and style from your template file. Besides global styles, your component stylesheet only cares about your component. To make components interactive, the framework creates a component class instance for each DOM component. It also facilitates communication between components by retrieve component instances from DOM elements.

The reason we keep everything on the client, is that we want to avoid the backend as long as possible. Why? Because it only slows you down. You don't want to wait until the backend has created the Domain Model and set up all the controllers. You don't want to have slow page loads and miss out on hot reloading. By using local json files you can mock all the data, and prepare for all possible scenarios.

Workflow

To better explain how Muban can benefit you, let's explain what a common workflow looks like. There are three different phases where all work passes through.

Develop.

Development starts by copying the project, installing the node modules, executing yarn dev and opening the browser at http://localhost:9000/.

After that you can just create a page by sg page blog-detail and a component by sg component hero-detail.

Any changes you make to your template, script or style will automatically update in the browser without manual reloads.

You can also choose to run yarn storybook and open http://localhost:9002/ to view your component in Storybook. This allows you to create multiple presets with different data to showcase and test different variations. It'll also display component documentation and source code.

You can run yarn build and upload the generated HTML pages to a preview server to get design and QA sign-off without ever needing a backend system.

When your site or a part of it is completed and signed off, it's time to integrate it in the backend system.

Running yarn build will generate bundled and minified scripts and styles that can be directly used in your server-rendered pages. It will also collect all the mock data and development templates so the person that's going to implement the templates in the backend will have a full overview. Storybook can also be used to gather information about components.

Depending on your server-side template language, the muban-convert-hbs module can transpile the Handlebars templates for you. It currently supports HTL, Django and Twig output templates. If you kept the json mock files and the actual backend data model similar, the templates hardly need any manual updates.

Integrate.

Update.

Of course, nothing is perfect the first time something is created. You get feedback, or something doesn't look quite right on a specific device. Whatever the reason, you'll have to update some components you created before.

By design, Muban tries to minimize the coupling between your templates and your scripts and styles. Because of this, most often your changes can be done in your script or style, without touching the template.

If you do need to update your template, you have to make a choice:

  1. You could completely ignore the Handlebars templates and only update your server-side templates. This means you have to run the complete backend to see and test your changes, and you'll lose the template hot reloading feature. Even worse, Storybook isn't up-to-date anymore, so you'll have to disband it.
  2. You make the updates the same way you have developed it. This will keep the development workflow optimal and allows you to keep using Storybook. The downside is that you have to re-integrate the changes in the server-side templates, which is duplicate work and mistakes could slip in.

Storybook

Inspired by React and Vue Storybook, it allows you to view all your components. It serves developers during the development phase, website owners to keep track of everything, and backend developers to do integration.

Development

Since Muban promotes component based development, we have Storybook to make this even easier.

Every component folder can contain a preset.js file that registers a component with Storybook. When scaffolding a component, a default preset is generated automatically


      storiesOf('Button', require('./button.hbs'))
        .add(
          'with Foo',
          'Just a normal button that says Foo.',
          `<hbs>
            {{> button text=text}}
          </hbs>`,
          { text: 'foo' },
        )
              

Every preset contains a name, description, a template and mock data. Using a custom webpack-loader, you can use inline Handlebars syntax to customize how your component is displayed on the page.

By adding multiple presets you can display your components in different scenarios, which could be hard to do when you only render your component on a single page.

Integration

Storybook can be a big help during integration. Besides displaying the components, it will also show a ton of information.

The component description can contain information on how and where the component should be used or what variations are possible by adding certain classes or properties.

It also shows source code in multiple tabs; the preset code, mock data, rendered HTML, Handlebars source, script source and template source.

Additionally it can even show a tab with the template converted to the backend template language using the muban-convert-hbs plugin. Not having to convert the template manually will save a lot of time!

Copyright © 2018 MediaMonks B.V.