Instalar o Node.js: verificar o funcionamento dos botões no servidor sem navegador

Para executar JavaScript em um servidor, primeiro é preciso instalar o Node.js. Instalei o Node.js 24.21.0 em um servidor WordPress com Nginx e Apache e, com o jsdom 30.1.3, verifiquei sem navegador o script dos botões de uma página web.
O nodejs do repositório padrão é o 16.20.2, mas o jsdom 30.1.3, usado para verificar scripts, exige Node.js 22.22.2 ou superior. Por isso, instalei pelo stream de módulo 24 do dnf.
1️⃣ Para que instalar Node.js e jsdom no servidor
Para verificar scripts de botões em um servidor, são necessárias duas coisas: Node.js e jsdom.
🔲 Node.js
O JavaScript normalmente roda dentro do navegador, mas, com o Node.js instalado, o servidor também consegue ler e executar JavaScript.
Instalar o Node.js é colocar também no servidor o ambiente de execução de JavaScript que antes só existia no navegador. Por isso o Node.js é usado para criar servidores web, montar comandos que processam muitos arquivos de uma vez ou carregar pacotes como o jsdom para verificar páginas. O Ghost também é um CMS que roda sobre o Node.js.
🔲 jsdom
O jsdom é um pacote do Node.js que lê o HTML e o transforma em um documento cujos botões podem ser clicados como em um navegador. Ele monta dentro do servidor, sem tela, a mesma estrutura de documento (DOM) que o navegador cria ao abrir uma página, então os scripts encontram os botões e mudam o texto como se estivessem em um navegador de verdade. Como não abre janela, roda no servidor com uma única linha de comando.
Ou seja, as verificações que uma pessoa fazia abrindo o navegador e clicando um por um passam a ser feitas pelo servidor com um comando. Por isso o jsdom também é usado para testar automaticamente o comportamento dos botões a cada correção, extrair de uma página só conteúdos como títulos e links ou ajustar em lote o HTML dos posts.
Se você baixa a página com PHP ou curl, só vê o HTML que chegou primeiro. O texto que muda depois de clicar em um botão só aparece quando o script é executado.
O navegador passa por quatro etapas: receber a página, ler a página, clicar no botão e mostrar na tela. O jsdom executa no servidor todas as etapas menos a de mostrar na tela, então a posição e o tamanho dos botões são verificados no navegador.
2️⃣ Antes de instalar: repositório padrão e streams de módulo
Antes de executar [dnf install nodejs], confira primeiro qual versão seria instalada. O nodejs do repositório padrão do AlmaLinux 9.8 é o 16.20.2.
dnf list --available nodejsAvailable Packages
nodejs.x86_64 1:16.20.2-8.el9_4 appstreamO repositório de módulos tem quatro streams: 18, 20, 22 e 24. Na data da verificação, o stream 22 estava na 22.23.2 e o 24 na 24.21.0.
dnf module list nodejsnodejs 18 common [d], development, minimal, s2i Javascript runtime
nodejs 20 common [d], development, minimal, s2i Javascript runtime
nodejs 22 common [d], development, minimal, s2i Javascript runtime
nodejs 24 common [d], development, minimal, s2i Javascript runtimeSegundo o registro do npm, o jsdom 30.1.3 exige 22.22.2 ou superior na linha 22, 24.15.0 ou superior na linha 24, ou 26 em diante. Os streams 22 e 24 atendem a essa condição.
3️⃣ Instalar o Node.js: dnf module
Desta vez instalei o stream 24 e, antes de executar, conferi com a opção [--assumeno] a lista de pacotes que seriam instalados.
dnf module install nodejs:24 --assumenoA lista tinha só cinco pacotes: nodejs, npm, nodejs-libs, nodejs-docs e nodejs-full-i18n. Não havia pacotes de servidor web, PHP nem kernel. Depois de conferir, faça a instalação com a opção [-y].
dnf module install -y nodejs:24Dependencies resolved.
==============================================================================================
Package Architecture Version Repository Size
==============================================================================================
Installing group/module packages:
nodejs x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 70 k
npm noarch 1:11.19.0-1.24.21.0.1.module_el9.8.0+321+1555b6a2 appstream 2.1 M
Installing dependencies:
nodejs-libs x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 24 M
Installing weak dependencies:
nodejs-docs noarch 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 5.3 M
nodejs-full-i18n x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 8.9 M
Installing module profiles:
nodejs/common
Enabling module streams:
nodejs 24
Transaction Summary
==============================================================================================
Install 5 Packages
Total download size: 40 M
Installed size: 185 M[Installing weak dependencies] lista as dependências fracas (weak dependencies), pacotes que vale a pena instalar junto. O download tem 40M e a instalação, 185M.
node -vv24.21.0npm -v11.19.0cat /etc/dnf/modules.d/nodejs.module[nodejs]
name=nodejs
stream=24
profiles=common
state=enabledO node foi instalado na 24.21.0 e o npm na 11.19.0. O único arquivo de configuração alterado pela instalação é o [/etc/dnf/modules.d/nodejs.module], que registra como ativos o stream 24 e o perfil common.
4️⃣ Instalar o jsdom e verificar o script de um botão
O jsdom é instalado com o npm em uma pasta de trabalho, e essa pasta é criada fora da raiz web.
mkdir ~/jsdom-test && cd ~/jsdom-test
npm init -y[npm init -y] cria o package.json com os valores padrão e, em seguida, o jsdom é instalado na mesma pasta.
npm install jsdomadded 36 packages, and audited 37 packages in 2s
8 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesnpm ls jsdomjsdom-test@1.0.0 /root/jsdom-test
└── jsdom@30.1.3Foram instalados 36 pacotes, incluindo o jsdom 30.1.3, com 0 vulnerabilidades conhecidas. A pasta node_modules da pasta de trabalho tem 26M.
node -e 'const { JSDOM } = require(`jsdom`); console.log(new JSDOM(`<h1>Olá</h1>`).window.document.querySelector(`h1`).textContent)'OláSe o jsdom ler como documento um HTML com uma única tag h1 e imprimir o texto dentro dela, [Olá], a verificação está concluída.
Verificar o script de um botão é conferir no servidor se o texto muda corretamente depois do clique. Como exemplo, criei na pasta de trabalho um arquivo HTML em que, ao clicar no botão [Copiar], o texto muda para [Copiado].
cat btn.html<button id="copy">Copiar</button>
<script>
document.getElementById('copy').addEventListener('click', function () {
this.textContent = 'Copiado';
});
</script>O script de verificação lê o arquivo HTML com o jsdom, executa os scripts e imprime o texto antes e depois do clique. Os erros de script aparecem em linhas que começam com [Erro:].
cat check.jsconst fs = require('fs');
const { JSDOM, VirtualConsole } = require('jsdom');
const vc = new VirtualConsole();
vc.on('jsdomError', (e) => console.log('Erro:', e.message));
const dom = new JSDOM(fs.readFileSync(process.argv[2], 'utf8'), {
runScripts: 'dangerously',
virtualConsole: vc,
});
const btn = dom.window.document.querySelector('#copy');
console.log('Antes do clique:', btn.textContent);
btn.click();
console.log('Depois do clique:', btn.textContent);node check.js btn.htmlAntes do clique: Copiar
Depois do clique: CopiadoDepois do clique, o texto muda para [Copiado], o que confirma que o script do botão funciona.
Um único erro de digitação no script muda o resultado. Rodei a mesma verificação com um arquivo em que o I maiúsculo de getElementById foi trocado por um l minúsculo.
sed 's/getElementById/getElementByld/' btn.html > btn-broken.html
node check.js btn-broken.htmlErro: Uncaught [TypeError: document.getElementByld is not a function]
Antes do clique: Copiar
Depois do clique: CopiarUm erro aparece na primeira linha e o script para, então o texto continua [Copiar] mesmo depois do clique.
Defini no botão, com CSS, largura de 120px e altura de 40px e depois imprimi o tamanho.
cat size.jsconst { JSDOM } = require('jsdom');
const dom = new JSDOM('<button id="copy" style="width:120px;height:40px">Copiar</button>');
const btn = dom.window.document.querySelector('#copy');
console.log('altura:', btn.offsetHeight, '/ largura:', btn.getBoundingClientRect().width);node size.jsaltura: 0 / largura: 0O jsdom não tem a etapa de desenhar na tela, então a altura e a largura saem como 0.
🔢 FAQ & conteúdo recomendado







ℹ️ Aviso de afiliados
O conteúdo deste site contém links de afiliados. Quando um visitante compra um produto ou serviço por meio de um desses links, o site recebe uma comissão do vendedor. O valor que o comprador paga (em promoções, ele diminui ↓) não aumenta por causa disso. Preços, descontos e informações de estoque valem para o momento em que o texto foi escrito e podem ter mudado, por isso confirme com o vendedor antes de comprar. Os produtos são escolhidos e avaliados por critérios próprios, e o recebimento de comissão não influencia a ordem de apresentação nem o conteúdo das avaliações.