получилось вывести только элементы первого уровня, но не могу понять, как заставить выводиться дочерние элементы
Рекурсия. Если в элементе есть непустой массив children, то делаете рекурсивный вызов функции, передавая ей этот массив.
Можно напрямую создавать элементы:
const createTreeElement = data =>
Array.isArray(data) && data.length
? data.reduce((ul, n) => {
const li = document.createElement('li');
const div = document.createElement('div');
div.textContent = n.name;
li.append(div, createTreeElement(n.children));
ul.append(li);
return ul;
}, document.createElement('ul'))
: '';
document.body.append(createTreeElement(data));
Или собрать соответствующую разметку:
const createTreeHTML = data =>
data instanceof Array && data.length
? `<ul>${data.map(n => `
<li>
<div>${n.name}</div>
${createTreeHTML(n.children)}
</li>`).join('')}
</ul>`
: '';
document.body.insertAdjacentHTML('beforeend', createTreeHTML(data));