Bobril – I – Getting Started

    0
    28

    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 on https://github.com/Bobris/Bobril.

    How to start

    Let’s start with 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 functionlity 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:

    npm i bobril-build -g

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

    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 debbuging and much more stuff you usually has to do manually in another frameworks.

    Let’s write a code

    For this purposes 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 following:

    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:

    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:

    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:

    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:

    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 usefull 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:

    bb b

    For mor information about bobril and bobril-build please visit the github pages:

    https://github.com/Bobris/Bobril

    https://github.com/Bobris/bobril-build

    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

    LEAVE A REPLY