Desde que lançamos o módulo NGINX JavaScript (njs) em 2015 (com seu nome original, nginScript) e o disponibilizamos para uso geral em 2017<.htmla>, continuamos adicionando novos recursos e aprimorando nossa implementação ao longo de dezenas de atualizações de versão. Normalmente, esperamos por uma versão do NGINX Plus para falar sobre os recursos de uma nova versão do NGINX JavaScript, mas estamos tão entusiasmados com a versão 0.7.7 que, desta vez, não podemos esperar!
As melhorias significativas no njs 0.7.7 ajudam a tornar sua configuração do NGINX ainda mais modular, organizada e reutilizável:
- Agora você pode declarar o código njs nos contextos em que ele se aplica em vez de declará-lo globalmente, aproximando seu código personalizado do ponto de uso.
- Os hooks no próprio código njs permitem que você modifique o comportamento de acordo com o contexto de execução.
- O novo objeto
fs.FileHandletorna as operações de arquivo mais eficientes.
Para saber mais sobre o njs e conferir a lista de casos de uso para os quais fornecemos exemplos de código, leia Aproveitando o poder e a praticidade do JavaScript em cada solicitação com o módulo JavaScript do NGINX em nosso blog.
Para obter uma lista completa de todos os novos recursos e correções de bugs do njs 0.7.7, consulte a documentação de Alterações.
Declarando código e variáveis JavaScript em contextos locais
Nas versões anteriores do njs, era necessário importar o código JavaScript e declarar as variáveis relevantes — com as diretivas js_import, js_path, js_set e js_var — no contexto de nível superior http ou stream, o equivalente a declarar variáveis globais no início de um arquivo principal. No entanto, as diretivas que efetivamente invocam as funções e variáveis JavaScript aparecem em um contexto filho — por exemplo, a diretiva js_content em um bloco location{} HTTP e a diretiva js_access em um bloco server{} de Stream. Isso gera dois problemas:
- Para quem está lendo a configuração, as declarações nos contextos
httpestreamsão essencialmente ruído, pois não há nenhuma indicação de onde o código e as variáveis associados são realmente usados. - Não fica claro, no contexto filho, onde o código e as variáveis foram importados e declarados. Embora recomendemos incluir os blocos
http{}estream{}somente no arquivo de configuração principal (nginx.conf) e usar a diretivaincludepara carregar arquivos de configuração menores e específicos para cada função a partir dos diretórios /etc/nginx/conf.d e /etc/nginx/stream.d, a configuração do NGINX é flexível — você pode incluir blocoshttp{}estream{}em vários arquivos. Isso pode ser especialmente problemático em ambientes nos quais várias pessoas trabalham na configuração do NGINX e nem sempre seguem as convenções estabelecidas.
No njs 0.7.7 e versões posteriores, você pode importar código e declarar variáveis nos contextos em que são usados:
- HTTP –
- Stream – Estas diretivas podem aparecer no contexto
server, bem como no contextostream:
Manter toda a configuração do njs para um caso de uso específico em um único arquivo também torna seu código mais modular e portável.
Por exemplo, nas versões anteriores do njs, ao adicionar um novo script, era necessário alterar tanto o arquivo nginx.conf (adicionando js_import e, possivelmente, js_path, js_set e js_var) quanto o arquivo no qual a função JavaScript é chamada (neste caso, jscode_local.conf).
Carregando exemplo de código…
Carregando exemplo de código…
No njs 0.7.7 e versões posteriores, toda a configuração relacionada à função util está em um único arquivo, jscode_integrated.conf:
Carregando exemplo de código…
Modificando o comportamento de acordo com o contexto de execução
Vários novos recursos do njs 0.7.7 permitem modificar o comportamento do seu código JavaScript de acordo com o contexto (fase de processamento) em que ele está sendo executado.
A propriedade HTTP r.internal Property
A propriedade HTTP r.internal é um sinalizador booleano definido como “true” para solicitações internas (que são processadas por blocos location{} que incluem a diretiva internal). Você pode usar o sinalizador r.internal para ramificar a lógica quando um script usa um manipulador de eventos genérico que pode ser chamado tanto em contextos internos quanto não internos.
As seguintes são classificadas como solicitações internas:
- Solicitações redirecionadas pelas diretivas
error_page,index,random_indexetry_filesdirectives - Solicitações redirecionadas pelo cabeçalho de resposta
X-Accel-Redirectde um servidor upstream - Subsolicitações invocadas pelas diretivas
auth_requestemirror, pelas diretivas do módulo ngx_http_addition_module, ou pelo comandoincludevirtualde Server Side Include (SSI) (compatível com o módulo ngx_http_ssi_module) - Solicitações alteradas pela diretiva
rewritedirective
Método de stream s.send() aprimorado
Em versões anteriores do njs, o método s.send() do Stream depende do contexto, pois a direção em que ele envia os dados é determinada pela localização (upstream ou downstream) do callback em que o método é chamado. Isso funciona bem para callbacks síncronos – para os quais o s.send() foi originalmente projetado –, mas não funciona com funções assíncronas, como ngx.fetch().
No njs 0.7.7 e versões posteriores, a direção é armazenada em um sinalizador interno separado, que o método s.send() pode então usar.
Operações de arquivo mais eficientes com o novo objeto fs.FileHandle() Object
O módulo de sistema de arquivos (fs) implementa operações em arquivos. O novo objeto FileHandle do módulo fs encapsula um descritor numérico de arquivo. As instâncias do objeto FileHandle são criadas pelo método fs.promises.open().
Use o objeto FileHandle para obter um descritor de arquivo, que pode ser usado posteriormente para:
- Executar funções como
read()ewrite()no arquivo - Abra um arquivo e realize operações de leitura e gravação em um local específico sem ler o arquivo inteiro
As seguintes propriedades de FileHandle foram implementadas (para obter informações sobre os argumentos obrigatórios e opcionais de cada propriedade, consulte a documentação):
filehandle.fdfilehandle.read()filehandle.stat()filehandle.write()filehandle.write()filehandle.close()
Estes métodos foram atualizados para oferecer suporte a FileHandle (consulte a documentação vinculada para obter informações sobre os argumentos de cada método):
fs.openSync()fs.promises.open()fs.fstatSync()fs.readSync()fs.writeSync()(buffer)fs.writeSync()(string)
Use o njs para aprimorar sua configuração
Com o njs 0.7.7, facilitamos o trabalho das suas equipes com o código njs e o compartilhamento desse código. Os contextos ampliados para as diretivas njs tornam ainda mais simples aprimorar a configuração do NGINX com código JavaScript personalizado. Você pode dar o primeiro passo rumo a um gateway de API, proxy reverso ou servidor web — e que seja mais do que apenas outro middleware ou componente de borda. Você pode integrá-lo à sua aplicação por meio de JavaScript, TypeScript, ou de módulos Node de terceiros, sem adicionar outro componente à sua stack. Tudo o que você precisa é do NGINX!
Tem alguma dúvida? Participe do Slack da comunidade NGINX e confira o canal #njs-code-review para saber mais, fazer perguntas e receber feedback sobre seu código njs.
Sobre o autor
Publicações relacionadas no blog

Como o F5 NGINX One aprimora o gerenciamento e a observabilidade
Descubra como o F5 NGINX One aprimora o gerenciamento e a observabilidade de ambientes híbridos e multicloud ao oferecer um console web centralizado baseado em SaaS, com insights em tempo real, conformidade automatizada e gerenciamento simplificado de configurações.

Do OpenAPI ao NGINX como gateway de API usando uma API declarativa
Descubra como transformar uma definição de esquema OpenAPI em uma configuração NGINX totalmente funcional, operando como um API Gateway com a segurança de um Web Application Firewall e um Portal do Desenvolvedor, usando uma abordagem declarativa de API.

Como gerenciar picos repentinos de tráfego e sobrecarga do servidor
Picos de tráfego e sobrecarga de servidores são preocupações sérias para varejistas online em qualquer época, mas especialmente durante a “Cyber Season” de compras de fim de ano. Detalhamos como você pode aproveitar as soluções de entrega de aplicações de nível de produção da NGINX para se preparar para aumentos repentinos de tráfego.

Distribuição segura de chaves privadas SSL com o NGINX
Descrevemos três maneiras progressivamente mais seguras de proteger chaves privadas SSL ao configurar o NGINX para processar tráfego HTTPS: permitir acesso de leitura apenas ao usuário root, criptografar as chaves com senhas armazenadas separadamente e distribuir as senhas a partir de um repositório central.
Agrupando solicitações de API em lotes com NGINX Plus e o módulo JavaScript do NGINX
O módulo JavaScript do NGINX lançado com o NGINX Plus R15 oferece suporte a subsolicitações, possibilitando uma classe totalmente nova de casos de uso para o NGINX Plus. Este exemplo completo também usa a API do NGINX Plus e os módulos de chave-valor para converter solicitações de API dos clientes em solicitações separadas para as APIs dos microsserviços que compõem um aplicativo.
Como superar o esgotamento de portas efêmeras no NGINX e no NGINX Plus
Confira dicas para evitar o esgotamento de portas efêmeras com ajustes no kernel do Linux, conexões keepalive e conexões vinculadas dinamicamente a endereços IP locais.