Nginx Js Minifier

14 Сен
2011

Часто бывает необходимо сжимать javascript на сайте и хочется чтобы это было автоматически без лишних манипуляций.
Данный модуль будет полезен тем, у кого на сайте установлен веб сервер nginx для отдачи статических файлов, а также веб сервер apache для обработки php скриптов.
Всю работу по уменьшению размера js файлов возьмёт на себя nginx, чтобы не грузить бэкенд в виде apache, который у нас занят обработкой php.
Предлагаю вашему внимаю perl модуль для веб сервера nginx.
Что необходимо для работы модуля ?
Веб сервер nginx с собранным модулем ngx_http_perl_module
Модули для Perl:
  • JavaScript::Minifier
  • Digest::MD5

Добавляем в конфиг nginx модули perl.
http {
...
perl_modules perl;
# Подключаем наши модули
perl_require JavaScript/Minifier.pm;
perl_require Minify.pm;
...
}

И небольшое изменение в конфиге nginx для сайта, чтобы он обрабатывал js файлы с помощью модуля:
server {
...
location ~ \.js$ {
root /home/user/site.ru;
perl Minify::handler;
}
...
}

Модуль использует для минификации javascript кода perl модуль JavaScript::Minifier, его также легко можно заменить на любой другой.
Как он работает ?
Сжатые файлы у нас хранятся в папке /tmp
При запросе js файла сервер nginx передаёт управление нашему модулю, который просчитывает хэш файла.
Проверяет, если файл существует в папке /tmp, то отдаёт его оттуда, если не существует, то сжимает его и сохраняет в папке /tmp
Минусы
Папку /tmp надо чистить регулярно, а то со временем в ней соберётся много сжатых js файлов.
О коде модуля
Изначально код модуля для минификации js где-то нашёл, но эта версия не проверяла наличие изменений в файле, а просто сохраняла сжатый js в папку /tmp и постоянно отдавала оттуда.
Я добавил проверку изменения файла с помощью md5 и немного подточил напильником 🙂
Сжатие CSS
Легко можно сделать использовав другой Perl модуль вместо JavaScript::Minifier и немного поправить конфиг nginx для обработки CSS с помощью модуля.
О посте
Не претендует на гениальность, но надеюсь кому-то пригодится.

В папке nginx создаём папку «perl» для хранения perl модулей веб сервера, а в ней файл Minify.pm c кодом:
package Minify;
use nginx;
use JavaScript::Minifier qw(minify);
use Digest::MD5;
sub md5sum{
my $file = shift;
my $digest = "";
eval{
open(FILE,$file) or die "Cant't find file $file\n";
my $ctx = Digest::MD5->new;
$ctx->addfile(*FILE);
$digest = $ctx->hexdigest;
close(FILE);
};
if($@)
{
print #@;
return "";
}
return $digest;
}
sub handler
{
my $r=shift;
my $cache_dir="/tmp"; # Cache directory where minified files will be kept
my $cache_file=$r->uri;
my $http_host = $r->header_in("Host");
my $prefix = "_";
my $uri=$r->uri;
my $filename=$r->filename;
return DECLINED unless -f $filename;

my $md5= md5sum($filename);
$cache_file=~s!/!$md5$prefix!g;
$cache_file=join("/", $cache_dir, $cache_file);
if (! -f $cache_file) {
open(INFILE, $filename) or die "Error reading file: $!";
open(OUTFILE, '>' . $cache_file ) or die "Error writting file: $!";
minify(input => *INFILE, outfile => *OUTFILE);
close(INFILE);
close(OUTFILE);
}
$r->send_http_header("application/javascript");
$r->sendfile($cache_file);
return OK;
}
1;
__END__
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх