Node.JS: library for modifying http responses

Some time ago I wrote a site with a backend on Express /Node.JS. There was a problem with the minimization of answers. I found many ready-made packages, but everyone had a problem - html after templates was not minified. As a result, I decided to write my own small and native bicycle - the web-minify library , which allows you to embed a hook before sending it to the client and modify the response.

Package installation


npm i @dmitriym09/web-minify --save

I think the best description of a library for a developer is code example =)

Example


web-minify - middleware function:

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;
    }
  }
]));

In this example, all responses with Content-Type containing the substring “css” will be intercepted. The response body is processed using csso , postcss , precss , autoprefixer . String is passed in the contentType parameter (the occurrence of String.prototype.indexOf () will be searched for or RegExp (RegExp.prototype.test ()). The minify parameter - Function (data: String, req: Request, res: Response) function, should return a String with a new body or Promise, which in turn is resolved by String. In case of non-catching exception, the client will receive a response of 500

As already said, most of the existing popular libraries with similar functionality well minify static files. However, the minification of the responses generated in the code (for example, html by the template engine) does not work. One of the problems is that the answer can be sent in parts, and for processing usually complete data is needed. Accordingly, you need to intercept all sending to the user, collect it and process and send it at the end. This should be taken into account when using web-minify : the terabyte file that you want to send to the client and which falls under contentType accumulates in memory.

Examples


HTML minification using html-minifier from unit tests


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(`


Test

Test

`); }); request(app) .get('/') .set('Accept', 'text/html; charset=utf-8') .expect('Content-Type', 'text/html; charset=utf-8') .expect('

Test

Test

') .expect(200) .end(done) });

Modifications to JSON and the Promise return code from unit tests


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)
});

Web-minify is available on github and in npm under the MIT license.

Thanks for attention! Criticism, suggestions and comments are welcome!

Also popular now: