Web Programming TutorialsLearn About HyperApp Virtual DOM and Virtual Nodes - HyperApp Concepts

Learn About HyperApp Virtual DOM and Virtual Nodes – HyperApp Concepts

In the last article, we discussed about the Hyperapp installation overview, along with a basic example where we explained the concept of View, Action, and State used in building Hyperapp application. In this article, we are going to explore about the virtual DOM (Document Object Model) concept in HyperApp also known as Virtual Node.

Virtual DOM

A Virtual DOM is nothing but the description of a DOM structure by using a tree of JavaScript nested objects i.e. Virtual Nodes. Every render cycle using HyperApp creates the virtual DOM treefrom scratch. Therefore, the view function can be called every time when the state of application gets changed and a newly generated tree can update the actual DOM on each render cycle. In HyperApp, a tree changes in few DOM operations after comparing the new virtual DOM with the last created DOM and as a result it leads to high efficiency because only few parts of nodes are required to change instead of recalculating the entire virtual DOM.

HyperApp API has h function which helps in the creation of virtual nodes in a very efficient way. Alternatively, virtual nodes can be created with JSX. JSX is nothing but the JavaScript language extension which is used to represent dynamic HTML. We need to compile JSX into h function calls by importing h statement as browsers do not understand JSX directly. In the following example, we are going to describe about this process using babel.

Getting Started with Hyperapp

Step 1: – First of all, we need to install all dependencies after specifying them in “package. json” file. Let’s define the project name as “hyperapp-virtual-dom”. We can install the required dependencies under the “node_modules” of the current project after creating a file “package. json” with the below details. It should be noted that this file should be present at the project root where we are going to execute the “npm install” command. The “npm install” command will download and install all the required dependencies version present in the “package. json” file as shown below.

Package. json

{
  "name": "hyperapp-virtual-dom",
  "version": "1.0.0",
  "description": "hyperapp Demo",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack --env production",
    "wipe": "rm -rf .git && git init && git add . && git commit -m 'initial commit'",
    "test": "jest --coverage --no-cache"
  },
  "author": "XYZ",
  "license": "Eduonix",
  "dependencies": {
    "hyperapp": "^1.1.2"
  },
  "devDependencies": {
    "babel-cli": "^6.22.2",
    "babel-core": "^6.22.1",
    "babel-loader": "^7.1.2",
    "babel-minify-webpack-plugin": "^0.2.0",
    "babel-plugin-transform-react-jsx": "^6.22.0",
    "babel-preset-env": "^1.6.1",
    "babel-preset-es2015": "^6.22.0",
    "css-loader": "^0.28.0",
    "eslint": "^4.13.1",
    "eslint-config-airbnb-base": "^12.0.0",
    "eslint-plugin-import": "^2.2.0",
    "eslint-plugin-jest": "^21.7.0",
    "eslint-plugin-react": "^7.5.1",
    "extract-text-webpack-plugin": "^3.0.0",
    "imports": "^1.0.0",
    "jest": "^22.1.4",
    "node-libs-browser": "^2.0.0",
    "webpack": "^3.4.0",
    "webpack-dev-server": "^2.4.2"
  }
}

Step 2: – Next, important file is “. eslintrc.js” and the content of this file is shown below. In this file, we have specified the required modules to bring up the Node.js application. In the current, Hyperapp JS application, we require below module exports.

module.exports = {
  'extends': 'airbnb-base',
  'plugins': [
    'import',
    'react',
    'jest',
  ],
  'rules': {
    'linebreak-style': 'off',
    'no-unused-vars': [2, { 'varsIgnorePattern': 'h' }],
    'react/jsx-uses-vars': 2,
  },
  'parserOptions': {
    'ecmaFeatures': {
      'jsx': true,
    },
  },
  'env': {
    'browser': true,
    'jest': true,
  }
};

Step 3: – Next, we need to create a “. babelrc” file. Below is the file content. Here, we are defining required plugins and presents.

{
  "plugins": [
    ["transform-react-jsx", { "pragma": "h" }]
  ],
  "presets": [
    ["es2015", {
      "es2015": {
        "modules": false
      }
    }],
  ],
}

Step 4: – Next important file is “webpack.config.js” and below is the content of this file. In this file, we have specified the vendor libraries, path, plugins, and module export which we are going to use in this hyperapp application.

const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const MinifyPlugin = require('babel-minify-webpack-plugin');
const webpack = require('webpack');

const plugins = [
  new ExtractTextPlugin({
    filename: './bundle.css',
    allChunks: true,
  }),
  new webpack.optimize.ModuleConcatenationPlugin(),
];

module.exports = function webpackStuff(env) {
  if (env === 'production') plugins.push(new MinifyPlugin());

  return {
    entry: [
      './src/index.js',
    ],
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, './'),
    },
    module: {
      rules: [{
        test: /\.js$/,
        loader: 'babel-loader',
        query: {
          presets: [
            'es2015',
          ],
          plugins: [],
        },
        include: [
          path.resolve(__dirname, './'),
        ],
      }, {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          use: 'css-loader?importLoaders=1',
        }),
      }],
    },
    plugins,
  };
};

Step 5: – Building Hyperapp view through Virtual DOM
In this example, we are going to use the virtual DOM where the view function is called every time we change the application state. The view function has the code logic for Virtual DOM and it get changes each time the application state changes as a result of the increase or decrease of the counter value (i.e. Basic +- counter computing application). HyperApp each time takes care to update DOM with greater efficiency by just replacing the parts of the DOM which are changed instead of the entire DOM. Given below is the detailed code logic for the above app implementation.
./src/actions/index.js
Here, we are defining the actions to increment or decrement the counter.

export default {
	  down_counter: value => state => ({ number: state.number - value }),
	  up_counter: value => state => ({ number: state.number + value })
};

./src/components/VirtualDOM.js
Here, the actual HyperApp code is defined. It decides the view of the application depending on the state and actions. This code is responsible for altering the view components and generating the virtual DOM to render using HyperApp.

import { h } from 'hyperapp';

export default (state, actions) => (
		    h("div", {}, [
		    h("h2", {}, [state.message]),
		    h("h1", {}, [state.number]),
		    h("button", { onclick: () => actions.down_counter(1) }, "ー"),
		    h("button", { onclick: () => actions.up_counter(1) }, "+")
		  ])
		);

./src/state/index.js
Here, we have defined an application state.

export default {
	  number: 0,
	  message : 'Virtual DOM',
};
./src/index.js

This is our entire application build which collaborates between state, actions and view.

import { h, app } from 'hyperapp';
import state from './state';
import actions from './actions';
import view from './components/VirtualDOM';


app(state, 
		actions, 
		view, 
		document.getElementById("app")
		);
./styles.css

Below are the styling specifications for the app.

html {
  line-height: 1;
}

body {
  align-items: center;
  background-color: white;
  display: flex;
  font-family: Arial Black, sans-serif;
  height: 100vh;
  justify-content: center;
  margin: 0;
  padding: 0;
  text-align: center;
  background:#3636c1;
  background:linear-gradient(to bottom, #3636c1 0%, #161658 100%);
}

h1 {
  color: white;
  text-align: center;
  font-size: 12em;
  font-weight: bold;

  margin: 0;
  padding-bottom: 20px;
}

h2 {
  color: white;
  text-align: center;
  font-size: 6em;
  font-weight: bold;

  margin: 0;
  padding-bottom: 20px;
}
button {
  background: green;
  border: 8px solid black;
  color: black;
  cursor: pointer;
  font-size: 5em;
  font-weight: bold;
  padding: .1em;
  min-width: 15vw;
}
button:active {
  outline: 4px solid black;
}
button:focus {
  outline: 4px solid black;
}
button + button {
  margin-left: 16px;
}
./index.html

It is the starting point where we will be calling our app which we have just built.

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type="text/css" href="styles.css">
  <script defer src="bundle.js"></script>
</head>
<body>
  <div id="app"></div>
</body>
</html>

Command to execute Hyperapp application
We need to execute “npm start” (as defined in “package. json” under scripts) at the project root of Hyperapp web application as shown below.
Hyperapp web application root
Output
Once the application is built successfully, we can see the application loaded at below URL [http:/localhost:8080/] as shown below.
V Dom 6

Source code for Hyperapp concept

Conclusion: –
In this article, we discussed about a Hyperapp concept with Virtual DOM or Nodes along with a suitable example.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -