Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web

Bobril - I - Getting Started

5.00/5 (13 votes)
29 Jul 2017CPOL6 min read 58.5K   257  
A simple introduction to bobril framework

 

bobril-logo

Introduction

In this article, we will learn the basics about bobril and create a simple application with one component. Then, we will take a look at how to setup the project simply by the npm.

Background

Bobril is a component-oriented framework inspired by React and Mithril. It combines advantages from both of them. It is fast, low size framework with rendering based on Virtual DOM. The main focus is on speed and simplicity of code generation. Bobril is about 8x faster than react (see vdom-benchmark).

Content and behavior of any page can be defined simply by composing JavaScript objects.

The page content rendering is based on comparison of Virtual DOMs. The application has some state in time and bobril application generates the Virtual DOM according to this state. Virtual DOM is an object representation of the resultant DOM. If some state-changing event occurs and the previous Virtual DOM is different than currently generated Virtual DOM, the real DOM will change according to this change.

Bobril is written by Boris Letocha (software architect and developer in GMC Software Technology).

Quote: Boris Letocha, author of the framework

Besides size and speed benefits, bobril has some very useful features which you will not find elsewhere. For example transparent emulation pointer-events:none or user-select:none in all browsers down to IE9. Transparent unification of mouse and touch events across all supported browsers including Chrome, IE10, IE11. Another feature I call it "Virtual CSS" - you can define styles in JS and it will transparently build optimal CSS in runtime. Image spriting. Image recoloring. Tight integration with TypeScript. Bobril-build enhancing your code during compile time, does optimal bundling similar to Rollup. Bobril removed some of limitations of React like component root does not need to be just one element. Directly includes Router and Drag and drop features. And much much more.

You can find more detailed information and examples here.

How to Start

Let's start with a simple TypeScript (typed JavaScript) example - traditional Hello World.

Installing Build System

The easiest way is to use directly the prepard build system bobril-build, which contains optimalized functionality for building bobril based applications, testing, translations, etc. Bobril-build requires node.js >= 6.*.* and npm >=3.*.*.

To install bobril build, pass the following command to the command line:

BAT
npm i bobril-build -g

We also recommend to install the tslint bobril-build plugin which generates tslint.json file for the project:

BAT
npm i typescript tslint -g
bb plugins -i bb-tslint-plugin

TSLint checks your TypeScript code for readability, maintainability, and functionality errors.

Now we can start with creating the project. So create some folder, e.g., sample1, create an empty file, index.ts in this folder and pass the following commands in its root:

npm init
npm i bobril --save
bb

These commands will:

  1. Initialize project as npm package. You can hit Enter for all questions.
  2. Install the bobril dependency
  3. Run bobril-build

Now the bobril-build runs in the interactive mode, which means it watches your code for changes, builds the application to the memory file system and serves it on the address http://localhost:8080.

The built application has resolved all dependencies, created the index.html, source maps for debugging and much more stuff you usually have to do manually in another frameworks.

Let's Write a Code

For this purpose, we recommend to use the Visual Studio Code with installed tslint and bobril plugins. Bobril-build is optimized for this editor and contains its own bobril extension with snippets and analysis tools.

So, open the sample1 folder in editor and change index.ts to look like the following:

JavaScript
import * as b from 'bobril';

b.init(() => {
    return { tag: 'h1', children: 'Hello World!' };
});

The b imortend from the bobril package represents the bobril world with all its available basic functions. The init function initializes the application with function returning the Virtual DOM. In the example is the Virtual DOM represented with the only one node - IBobrilNode - of tag 'h1' with content 'Hello World'.

Yes, it is that simple. Except the string, the children property can be assigned with another IBobrilNode or with an array of IBobrilNode, so we can compose the whole tree of the DOM.

Now take a look to the http://localhost:8080 address in your browser. You can see your first application written with bobril!

Components

Bobril is a framework focusing on components and for Virtual DOM composition, we can define easy-to-use components. Let's prepare a button component.

Add a new file button.ts with the following content:

JavaScript
import * as b from 'bobril';

export interface IButtonData {
    title: string;
    onClick?: () => void;
}

interface IButtonCtx extends b.IBobrilCtx {
    data: IButtonData;
}

export const button = b.createComponent<IButtonData>({
    render(ctx: IButtonCtx, me: b.IBobrilNode) {
        me.tag = 'button';
        me.children = ctx.data.title;
    },
    onClick(ctx: IButtonCtx): boolean {
        if (ctx.data.onClick) {
            ctx.data.onClick();
        }

        return true;
    }
});

export default button;

The b.createComponent function accepts an object defining the behaviour of component in its lifecycle. This lifecycle defining functions like init, render, postRender, etc. are defined by interface IBobrilComponent. The description of each function can be found in comments of bobril in its index.ts file. Our button uses the render and onClick functions which accept the ctx (context) as a first parameter.

Context is a storage for the current state of the specific component instance, e.g., for each specific button - the specific node in Virtual DOM.

The context interface IButtonCtx extending the IBobrilCtx has predefined member data which is automatically assigned by bobril in Virtual DOM tree rendering. It is prepared to be used with own IButtonData interface definition.

This data member is designed to be used as an input information for a component. It can define how the component should look like and behave. So the button in the example has title and onClick callback defined from the outside.

The data onClick callback is called in the onClick lifecycle function defined again by the IBobrilComponent interface.

Now the button component is ready to be used in index.ts so we can change it to look like the following:

JavaScript
import * as b from 'bobril';
import { button } from './button';

b.init(() => {
    return [
        { tag: 'h1', children: 'Hello World!' },
        button({ title: 'Click Me!', onClick: () => alert('Yeah! I was clicked!') })
    ];
});

After automatic recompile, you can open this page and see how the bobril is working.

The classic import with alias can be used as well:

JavaScript
import * as btn from './button';

Bring It to Life

If we need to make some operations (e.g., as a reaction on some backend event), change the state and tell bobril that the re-render of Virtual DOM is needed, we can simply call the b.invalidate() function and the bobril re-calls the function provided to the b.init function. To try it, we can simply change the code:

JavaScript
import * as b from 'bobril';
import { button } from './button';

let counter = 0;

b.init(() => {
    setTimeout(() => { counter++; b.invalidate(); }, 1000);

    return [
        { tag: 'h1', children: 'Hello World!' },
        button({ title: 'Click Me!', onClick: () => alert('Yeah! I was clicked!') }),
        { tag: 'p', children: counter.toString() }
    ];
});

It adds a new element with a counter increasing every 1000 ms. If you need to call b.invalidate inside of some component, use it with ctx as a parameter, so b.invalidate(ctx). It will perform rendering of the specific component only.

Bobril contains lots of other really useful functions like styleDef to define styles as objects and prepare them for use by style function. Other useful functions are routes and route to define routing between pages in application, etc.

Notes

To build, minify and bundle your application to dist folder, just type the command:

BAT
bb b

For more information about bobril and bobril-build, please visit the github pages below:

History

  • 2017-07-30: Revision (bobril-build@0.71.0, bobril@7.3.2, TS 2.4.2)
  • 2017-01-02: Revision (bobril-build@0.59.2, bobril@5.2.1)
  • 2016-11-04: Revision (bobril-build@0.50.1, bobril@4.49.0)
  • 2016-05-26: Changed to use only the bobril-build system (bobril-build@0.36.2, bobril@4.41.0)
  • 2015-12-16: Changed to simpleApp based on bobril-build
  • 2015-11-22: Added VS Code tasks configuration
  • 2015-11-17: Added link to vdom-benchmark
  • 2015-11-08: Update for version 4.8.2 - added helpers
  • 2015-10-28: Article created on version 4.4.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)