DICA: Como deixar sua página WEB dinâmica com banco de dados utilizando Node.JS

Fala galera, quando precisei dessa solução apanhei um pouco para achar algo completo e sem erros, após várias tentativas cheguei num resultado simples e satisfatório e estou compartilhando aqui com todos.

A ideia é deixar suas páginas WEB desenvolvidas em Node.JS totalmente dinâmicas com banco de dados MySQL, ou seja, se você alterar algo no banco de dados refletirá na página front-end ao usuário, isso tanto para uma consulta simples numa única tabela quanto para várias consultas em várias tabelas, podendo atualizar todos os elementos da página, segue a solução:

Arquivo rotas.js é onde tem minhas rotas de acordo com o endereço acessado no navegador:

module.exports = () => {

    //Instanciando o Router do express
    var express = require('express');
    var rotas = express.Router();

    //Rotas do site
    const { pageSite } = require('../controller/site/site.js')();//Se acessar algum endereço  abaixo entra na rota que está no '../controller/site/site.js'
    rotas.get('/', pageSite); //localhost:3000 (site)

    //Exportando este módulo
    return rotas;
};

Arquivo site.js é onde eu renderizo minha página .ejs que é de fato minha página front-end apresentada ao usuário, na renderização é que passo os dados vindos do BD:

//Importando arquivo site-model.js que possui a classe com as funções de consulta
const DB = require('./site-model');

//Importando e instanciando o MySQL para utilizar no construtor da classe
const mysql = require('mysql2');
const config = require('./../../database/config');
const conn = mysql.createConnection(config);

module.exports = () => {

  return {

    //Rota pageSite
    pageSite: (req, res, next) => {

      //Instanciando a classe e passando a conexão no construtor
      let DBModel = new DB(conn);

      //Renderizando
      (async function () {

        //Gravando o resultado nas variáveis pela classe DB que está no arquivo site-model.js
        let section0 = await DBModel.getSection0();
      //let outraVariavel = await DBModel.getOutraConsulta();

        //Renderizando a página com os resultados da consulta
        res.render('./site/index', {

          DTSection0: section0
       //,DTOutro: outraVariavel

        });

      })();

    },

};//return

}//module.exports

E agora o arquivo site-model.js, aqui temos as funções e consultas que são utilizadas no arquivo site.js na renderização da página:

//Classe de consultas para o site
class DB {

    //Construtor que recebe a conexão quando instanciado a classe
    constructor(db) {
        this.db = db;
    }

    //--------------------------------------- Funções internas

    //Consulta sem parâmetro
    async doQuery(queryToDo) {
        let pro = new Promise((resolve, reject) => {
            let query = queryToDo;
            //Executando a consulta
            this.db.query(query, function (err, result) {
                if (err) throw err;
                resolve(result);
            });
        })
        //Retornando o resultado
        return pro.then((val) => {
            return val;
        })
    }

    //Consulta com parâmetro
    async doQueryParams(queryToDo, array) {
        let pro = new Promise((resolve, reject) => {
            let query = queryToDo;
            //Executando a consulta com parâmetro
            this.db.query(query, array, function (err, result) {
                if (err) throw err;
                resolve(result);
            });
        })
        //Retornando o resultado
        return pro.then((val) => {
            return val;
        })
    }

    //--------------------------------------- Funções exportadas

    /**
     * Funções contendo os selects responsáveis por retornar o resultado caso
     * chamada lá no arquivo site.js */
    async getSection0() {//Site
        let query = "SELECT * FROM section_0 ORDER BY cod DESC";
        return this.doQuery(query)
    }

    /*
    async getOutraConsulta() {//Site
        let query = "Outro Select";
        return this.doQuery(query)
    }*/

};

//Exportando esta classe
module.exports = DB;

E por fim como receber isso na página, no meu caso estou usando .ejs:

        <!-- Título -->
        <% DTSection0.forEach(function(row){ %> <!-- Aqui estou passando pelo DTSection0 -->

        <div class="row-center">
            <div class="wow fadeInUp" data-wow-duration="1s" data-wow-delay="300ms">
                <h2><%= row.titulo %></h2> <!-- Aqui o campo da tabela -->
            </div>
        </div>

        <!-- Sub-Título -->
        <div class="row-center">
            <div class="wow fadeInUp" data-wow-duration="1s" data-wow-delay="500ms">
                <h4><%= row.sub_titulo %></h4> <!-- Aqui o campo da tabela -->
            </div>
        </div>

        <% }); %> <!-- Aqui fecho o forEach -->

Beleza galera, é isso, espero que ajude.

o jeito mais facil é colocar um template enguine. ve o bootstrap e admin-lte. ai voce integra a sua app.