- PVSM.RU - https://www.pvsm.ru -
Некоторое время назад писал сайт с бэкендом на Express [1]/Node.JS. Возникла проблема с минификацией ответов. Нашел много готовых пакетов, но у всех была проблема — не минифицировался html после шаблонов. В итоге принял решение написать свой маленький и родной велосипед — библиотеку web-minify [2], позволяющую встроить хук перед отправкой клиенту и модифицировать ответ.
npm i @dmitriym09/web-minify --save
Думаю, самое лучшее описание библиотеки для разработчика — пример кода=)
web-minify [2] — 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;
}
}
]));
В данном примере будут перехватываются все ответы с Content-Type, содержащие подстроку «css». Тело ответа обрабатывается с помощью csso [3], postcss [4], precss [5], autoprefixer [6]. В параметре contentType передается String (будет искаться вхождение String.prototype.indexOf()) или RegExp (RegExp.prototype.test()). Параметр minify — функция Function(data:String, req:Request, res:Response), должна возвращать String с новым телом или Promise, который в свою очередь разрешается String. При неотловленом исключении клиент получит ответ 500.
Как уже сказал, большинство существующих популярных библиотек с похожим функционалом хорошо минифицирует статические файлы. Однако минификация сгенерированных в коде (например html шаблонизатором) ответов не работает. Одна из проблем — ответ может отправляться частями, а для обработки обычно нужны полные данные. Соответственно нужно перехватывать все отправки пользователю, собирать и уже в конце обрабатывать и отсылать. Это нужно учитывать при использовании web-minify [2]: тот терабайтный файл, который вы хотите отправить клиенту и который попадает под contentType, накапливаться в памяти.
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)
});
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 [2] доступна на github [2] и в npm [8] под лицензией MIT.
Спасибо за внимание! Критика, предложения и комментарии приветствуются!
Автор: dmitriym09
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/294812
Ссылки в тексте:
[1] Express: https://github.com/expressjs/express.git
[2] web-minify: https://github.com/dmitriym09/web-minify
[3] csso: https://github.com/css/csso.git
[4] postcss: https://github.com/postcss/postcss.git
[5] precss: https://github.com/jonathantneal/precss.git
[6] autoprefixer: https://github.com/postcss/autoprefixer.git
[7] html-minifier: https://github.com/kangax/html-minifier.git
[8] npm: https://www.npmjs.com/package/@dmitriym09/web-minify
[9] Источник: https://habr.com/post/425371/?utm_campaign=425371
Нажмите здесь для печати.