Riot 5

Basically, if you are new to web programming or have already acquired a foundation in JavaScript it will be natural for you to put what you have learned into practice, you will see that Riot 5 is a library that you can quickly connect to by softening frustration as a beginner or interested programmer, in more sophisticated words, less learning curve by keeping aspects close to the standard. I think that after having some minimal practice with HTML and javascript (2015+) is perfect to know it, you can even stay connected with it if you like its simplicity, small size and speed of response.

As a developer, I got to use the first version of Angular, then a little bit of the new versions in proof of concept with Ionic. I was using some months ReactJS and it was funny but at that time its license was something peculiar. I took a look at Vue and although I saw similarities with Angular I didn’t get the idea of having to use templates with a prefix (v-). When I found Riot it was so simple and natural that I took the risk to give it a chance until its evolution to version 5, thanks to Gianluca Guarini for his contribution.

In the OnMind platform (of which I am the author) the path is well defined, at least for the current version has been established the programming of our visual components primarily under javascript, and if you ask for any library we support Riot 5 as “first-class” (first class) in our components built for a software that is oriented mainly to the internal management of businesses under own parameters. Even for native integration with mobiles it can be mixed with Capacitor. While someone may be in research on similar technologies (such as ReactJS, Angular, Vue or other), is beginning to learn about the subject or take their opinions, for OnMind is a fact and path chosen in our first version, being open to revision in future version, which does not occupy time at the moment.

The video illustrates an example found in the article about Capacitor + Riot

Riot & HTML

Riot uses HTML template, at the bottom of the file you can incorporate <style></style> and <script></script>

Now, If Riot 5 is close to the HTML standard, what is the difference or what does it add that needs to be learned?. In the essential sense of the things, I would cite in principle only 3 aspects:

  1. Expressions between {} keys, which are used to show content in a dynamic way, for example a title in a programmed way in a bilingual page.
  2. Conditions if to evaluate whether or not a HTML tag is displayed according to an expression.
  3. each cycles to dynamically process data frequently used in lists, tables, selection options or similar.

Additionally, it is required to understand aspects such as the notion of web components (which are presented as custom tags and are pieces for the visual interface), the life cycle (events for HTML DOM management), incorporation of elements or subcomponents in slots, as well as some styles (CSS3). I present this essential guide in my own way, I hope it will be of great help and I’m glad if it sounds of your interest to try or get started with RiotJS.

Essential example

<!DOCTYPE html>
<html>
    <head>
        <title>Riot 5 - Hi there!</title>
    </head>
    <body>
        <my-tag></my-tag>

        <script src="https://cdn.jsdelivr.net/npm/riot@4/riot+compiler.min.js"></script>
        <script src="my-tag.riot" type="riot"></script>
        <script type="module">
            (async function main() {
                await riot.compile()
                riot.mount('my-tag')
            }())
        </script>
    </body>
</html>

Basically, the interactive Riot compiler is invoked first using riot+compiler.min.js.
When a component is created, for example a my-tag.riot file, it is included as script and a structure close to the HTML standard can be used, as will be seen below.

Tags or Web Components

<my-tag>
    <h3>Hi there!</h3>
    This is { state.name }

    <script>
        export default {
            state: {
                name: 'my first tag'
            }
        }
    </script>
</my-tag>

> For internal or alterable properties the reserved word `state` is used, while to receive properties the reserved word `props` is used, for example:

```html
    <my-tag title="Welcome"></my-tag>

In this case you would receive “Welcome” in props.title, value that is passed to the component and that is not alterable within it. However, dynamic expressions can be used to send the title but that would be something else.

Quick Start Project

Next we will see an example in which we can do an exercise avoiding compiling in execution time, that is to say, including the components ready to use. Technologies such as Webpack (file packer or web resources) will be combined and a local web server is required. To start with, create a folder that corresponds to the example project and in which the required NodeJS modules will be installed. Therefore, there the file package.json should be initialized by executing the command npm init and installing the Webpack and Riot modules, as well:

npm init
npm i riot @riotjs/webpack-loader @riotjs/compiler -D
npm i webpack webpack-cli -D

Since Webpack requires a configuration file, usually called webpack.config.js, we initialize it (creating it in an editor) with the following content:

const path = require('path');

module.exports = {
  entry: './src/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.riot$/,
        exclude: /node_modules/,
        use: [{
          loader: '@riotjs/webpack-loader',
          options: { hot: false }
        }]
      }
    ]
  }
}

We modify the configuration file package.json generated by npm init, to incorporate the startup launcher or start task (under scripts), as well:

  "scripts": {
    "start": "webpack --mode development"
  },

We create a index.html file with the following content:

<!DOCTYPE html>
<html>
    <head>
        <title>Riot 5 - Hi there!</title>
    </head>
    <body>
        <div id="app"></div>
        <script src="dist/app.bundle.js"></script>
    </body>
</html>

In addition, we open a src folder including the component file in Riot, for example my-tag.riot, with the following content:

<my-tag>
    <h3>{ props.title }</h3>
    This is { state.name }

    <script>
        export default {
            state: {
                name: 'my first tag'
            }
        }
    </script>
</my-tag>

We also created under the src folder the app.js file that will be used as the main script to arm the package with Webpack. We place the following content:

import {component} from 'riot'
import Tag from './my-tag.riot'

component(Tag)(document.getElementById('app'), {
  title: 'Hi there!'
})

If you have installed a basic NodeJS web server as http-server or now, even with Python using the python -m SimpleHTTPServer 8000 command line, simply start it and open your browser on the respective port (usually 8080), entering something like localhost:8080 in the address.

At the end we have an initial project with the following file inventory:

File Description
dist/app.bundle.js Torn or distributable script file
src/app.js Main script file to build the package
src/my-tag.riot Web component file or tag
index.html Start page of the web application or SPA
package.json Package or module configuration file NodeJS
webpack.config.js Configuration file for application distribution or packaging

Expresiones

Basicamente se usan expresiones del lenguaje Javascript delimitadas por signos de llaves ({}) conforme al contexto, usando por ejemplo props o state.

{ state.value }
{ props.value || 'its string text' }
<p class={ this.selected: true }>
<button onclick={ hint }>

<script>
    export default {
        hint (e) { console.info('Ok!') }
    }
</script>

This last example block actually corresponds to events that are handled in a way similar to any expression

Conditional

You can handle validation points or conditions to hide or show something using if with Javascript expressions.

<div if={ state.ok }>...</div>

Loops

If you are going to process content that requires more dynamics, you can use each when dealing with arrays or iterations, for example, for tables or lists.

<ol>
    <li each={ item in props.list }>{ item.name }</li>
<ol>
<ol>
    <li each={ (row,i) in state.list }>{ i } - { row.name }</li>
<ol>

This last example illustrates the use with an arrangement also printing its index

Styles (CSS)

If you were wondering how you can apply custom styles somewhere in the component, just keep using <style> as in html, so if you’re a programmer with some vacuum on css and you have team collaboration, a web designer could guide you.

<my-tag>
    <h1>Title</h1>

    <style>
        h1 {
            font-family: Arial;
        }
    </style>
</my-tag>

Life Cycle (Riot Events)

Perhaps this is one of the most key points to assimilate for an insider in this bookstore. The life cycle of a component under Riot corresponds to the way of interacting internally with the DOM (this type of libraries facilitate a work in which the content is manipulated) and the instances through which a component passes from the moment it is prepared for use (onBeforeMount) until the event in which it is removed (onUnmounted), in case of intervening in its behavior in a programmed way, that is to say, it is possible to personalize the events if necessary. Let’s see then the 6 events to know.

Event Description
onBeforeMount Before the component is mounted on the page
onMounted Right after the component is mounted or rendered for the first time (or each time it is reassembled)
shouldUpdate Validation point to proceed with a visual update or not according to implemented logic. It must return true or false and is evaluated with the parameters newProps for new received property values, currentProps for the properties as they are, even this for any other internal property, so that it is possible to resolve the necessary conditions just before starting any update inside the component.
onBeforeUpdate Just before performing the update
onUpdated Just after the component is updated
onBeforeUnmount Before the component is removed
onUnmounted When the component is removed
export default {
    onBeforeMount(props, state) {},
    onMounted(props, state) {},
    shouldUpdate(newProps, currentProps) {},
    onBeforeUpdate(props, state) {},
    onUpdated(props, state) {},
    onBeforeUnmount(props, state) {},
    onUnmounted(props, state) {}
}

To refresh the DOM or apply update the following invocation is made:

this.update()
this.update({ data: 'hi' })

Injecting HTML into a TAG (Slot)

<my-tag>
    <slot />
</my-tag>

The above is done in the TAG definition, at the time of use the following is done:

For multiple slots these must first be defined with name.

<my-tag>
    <h1>
        <slot name="one" />
    </h1>
    <div>
        <slot name="two" />
    </div>
</my-tag>

When invoked, the slot attribute is used as follows:

<div>
    <span slot="one">Welcome</span>
    <span slot="two">John Doe</span>
</div>

It may seem like another way to do things without using properties, but this is because the examples are at an essential level. What is being suggested is an anatomy for different scenarios where a whole block of HTML is injected into our component and it must know which part it corresponds to.

Sub-components

Unlike the use of native HTML5, when within a component what is required is to use another within it, the file must be imported and indicate the subcomponent within the element components in the definition. For example:

    <my-tag>
        <my-sub />
    </my-tag>

    <script>
        import MySub from './my-sub.riot'
        export default {
            components: { MySub }
        }
    </script>

Note that a naming convention is used for labels such as my-sub and imported with a different name where the first letter of each name is capitalized and the hyphen is omitted, thus using in the script a name such as MySub. The my-sub.riot file should contain the respective code for the subcomponent.

Rendered from Server (SSR - Node.js)

If you’ve been motivated to use Riot for static web pages (where the server side doesn’t involve) things don’t stop there. This library has a small size and a good response time, so one would wonder how necessary a rendering from the server would be, but if it becomes necessary something doubly dynamic it is also possible to do it. To use Riot from the server requires Node.js, you could check the output with the following example:

<my-tag>
    <h3>Hi there!</h3>
</my-tag>

The previous content would correspond to a file for the tag. Assuming that the previous file was named hello.tag, a main javascript file (e.g. index.js) would be opened as the following:

import render from '@riotjs/ssr'
import Hello from './hello.riot'

const html = render('hello', Hello, { some: 'something more' })

console.log(html)

© 2019 by César Arcila