function h(tag, children) {
  return { tag, children }
}
/**
 * transform the ast to vnode
 *
 *   { type: 'tag', tag:'div', children: [...] }   => h("ul", [...])
 * @param ast {object} - { type: 'tag', tag:'div', children: [...] }
 * @returns {object} vnode = h("ul", [...])
 */
const transformer = ast => {
  const getChildren = children => {
    if (!children) return undefined;
    else if (children.length === 0) return undefined;
    else if (children.length === 1) return transformer(children[0]);
    else return children.map(transformer);
  }
  if (ast.type === 'Root')
    return h('Root', getChildren(ast.children))
  else if (ast.type === 'tag')
    return h(ast.tag, getChildren(ast.children))
  else if (ast.type === 'text')
    return ast.content
  else throw new Error('[@@@@@@] unknown ast type !!')
}
const ast01 = {
  "type": "Root",
  "children": [
    {
      "type": "tag",
      "tag": "div",
      "children": [
        {
          "type": "text",
          "content": "Hello World"
        }
      ]
    }
  ]
}
const vnode01 = transformer(ast01)
console.log(vnode01.toString());
/*
  h("Root", [ h("div", "Hello World") ]);
 */
<body>
<div id="app"></div>
<script>
  const h = (tagName, children) => {
    const element = document.createElement(tagName)
    if (typeof children === 'string')
      element.innerText = children
    else if (Array.isArray(children))
      children.forEach(child => element.appendChild(child))
    else if (typeof children === HTMLElement)
      element.appendChild(children)
    return element
  }
  const mountIt = (selector, element) => {
    document.querySelector(selector).appendChild(element)
  }
  const App = h("ul", [
    h("li", "Item_1"),
    h("li", "Item_2")
  ]);
  mountIt('#app', App);
</script>
</body>