Node.JS: biblioteca para modificar respostas http

Algum tempo atrás, escrevi um site com um back-end no Express /Node.JS. Houve um problema com a minimização de respostas. Encontrei muitos pacotes prontos, mas todo mundo tinha um problema - html depois que os modelos não eram minificados. Como resultado, decidi escrever minha própria bicicleta pequena e nativa - a biblioteca de redução da Web , que permite incorporar um gancho antes de enviá-lo ao cliente e modificar a resposta.

Instalação do pacote


npm i @dmitriym09/web-minify --save 

Eu acho que a melhor descrição de uma biblioteca para um desenvolvedor é exemplo de código =)

Exemplo


web-minify - função de middleware:

 const htmlminify = require('html-minifier').minify; const csso = require('csso').minify; const postcss = require('postcss'); const precss = require('precss'); const autoprefixer = require('autoprefixer'); const minify = require('web-minify'); app.use(minify([ { contentType: /css/, minify: async (data, req, res) => { let resData = (await postcss([precss, autoprefixer]).process(data, { from: undefined })).css; resData = csso(resData).css; return resData; } } ])); 

Neste exemplo, todas as respostas com o Tipo de conteúdo que contêm a substring "css" serão interceptadas. O corpo da resposta é processado usando csso , postcss , precss , autoprefixer . A cadeia é passada no parâmetro contentType (uma entrada será pesquisada por String.prototype.indexOf ()) ou RegExp (RegExp.prototype.test ()). O parâmetro minify - Função (data: String, req: Request, res: Response), deve retornar uma String com um novo corpo ou Promise, que por sua vez é resolvido por String. Em caso de exceção sem captura, o cliente receberá uma resposta de 500.

Como já foi dito, a maioria das bibliotecas populares existentes com funcionalidade semelhante minimiza bem os arquivos estáticos. No entanto, a minificação das respostas geradas no código (por exemplo, html pelo mecanismo de modelo) não funciona. Um dos problemas é que a resposta pode ser enviada em partes e, para o processamento, geralmente são necessários dados completos. Assim, você precisa interceptar todo o envio ao usuário, coletá-lo, processá-lo e enviá-lo no final. Isso deve ser levado em consideração ao usar o web-minify : o arquivo de terabyte que você deseja enviar ao cliente e que se enquadra no contentType se acumula na memória.

Exemplos


Minificação HTML usando html-minifier a partir de testes de unidade


 const htmlminify = require('html-minifier').minify; it('HTML', (done) => { const app = createServer([minify([ { contentType: 'html', minify: (data) => { let res = htmlminify(data, { removeAttributeQuotes: true, collapseWhitespace: true, conservativeCollapse: false, decodeEntities: true, keepClosingSlash: false, preserveLineBreaks: false, preventAttributesEscapin, processConditionalComments: true, removeAttributeQuotes: true, removeComments: true, trimCustomFragments: true, useShortDoctype: true }); return res; } } ])], function(req, res) { res.setHeader('Content-Type', 'text/html; charset=utf-8'); res.end(`<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> </head> <body> <h1>Test</h1> <p>Test</p> </body>`); }); request(app) .get('/') .set('Accept', 'text/html; charset=utf-8') .expect('Content-Type', 'text/html; charset=utf-8') .expect('<!doctype html><html lang=en><head><meta charset=utf-8></head><body><h1>Test</h1><p>Test</p></body></html>') .expect(200) .end(done) }); 

Modificações no JSON e no código de retorno Promise de testes de unidade


 it('JSON', (done) => { const app = createServer([minify([ { contentType: /json/, minify: (data, req, res) => { return new Promise(function(resolve, reject) { try { res.statusCode = 456; let o = JSON.parse(data); o.dt = new Date('2018-09-28T11:05:13.492Z') resolve(JSON.stringify(o)) } catch(exc) { reject(exc) } }) } } ])], function(req, res) { res.setHeader('Content-Type', 'application/json; charset=utf-8'); res.end(JSON.stringify({a: 12})); }); request(app) .get('/') .set('Accept', 'applicatio3n/json; charset=utf-8') .expect('Content-Type', 'application/json; charset=utf-8') .expect('{"a":12,"dt":"2018-09-28T11:05:13.492Z"}') .expect(456) .end(done) }); 

O Web-minify está disponível no github e no npm sob a licença MIT.

Obrigado pela atenção! Críticas, sugestões e comentários são bem-vindos!

Source: https://habr.com/ru/post/pt425371/


All Articles