«1. Обзор
В этой статье показано, как минимизировать ресурсы Javascript и CSS на этапе сборки и обслуживать полученные файлы с помощью Spring MVC.
Мы будем использовать YUI Compressor в качестве базовой библиотеки минификации и плагин YUI Compressor Maven, чтобы интегрировать его в наш процесс сборки.
2. Настройка плагина Maven
Во-первых, нам нужно объявить, что мы будем использовать плагин компрессора в нашем файле pom.xml и выполнить цель сжатия. Это сожмет все файлы .js и .css в папке src/main/webapp, так что foo.js будет минимизирован как foo-min.js, а myCss.css будет минимизирован как myCss-min.css:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
</plugin>
Наш каталог src/main/webapp содержит следующие файлы:
js/
├── foo.js
├── jquery-1.11.1.min.js
resources/
└── myCss.css
После выполнения пакета mvn clean сгенерированный файл WAR будет содержать следующие файлы:
js/
├── foo.js
├── foo-min.js
├── jquery-1.11.1.min.js
├── jquery-1.11.1.min-min.js
resources/
├── myCss.css
└── myCss-min.css
3. Сохранение имен файлов прежними
На этом этапе, когда мы запускаем mvn clean package, плагин создает foo-min.js и myCss-min.css. Поскольку мы изначально использовали foo.js и myCss.css при обращении к файлам, наша страница по-прежнему будет использовать исходные неминифицированные файлы, поскольку минифицированные файлы имеют другие имена, чем исходные.
Чтобы избежать использования как foo.js/foo-min.js, так и myCss.css/myCss-min.css, а также минимизировать файлы без изменения их имен, нам нужно настроить плагин с опцией nosuffix следующим образом:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<nosuffix>true</nosuffix>
</configuration>
</plugin>
Теперь, когда мы запускаем mvn clean package, у нас будут следующие файлы в сгенерированном файле WAR:
js/
├── foo.js
├── jquery-1.11.1.min.js
resources/
└── myCss.css
4. Конфигурация плагина WAR
Сохранение имен файлов имеет побочный эффект. Это приводит к тому, что подключаемый модуль WAR перезаписывает уменьшенные файлы foo.js и myCss.css исходными файлами, поэтому у нас нет уменьшенных версий файлов в окончательном выводе. Файл foo.js содержит следующие строки перед минификацией:
function testing() {
alert("Testing");
}
Когда мы изучаем содержимое файла foo.js в сгенерированном WAR-файле, мы видим, что он имеет исходное содержимое, а не уменьшенное содержимое. Чтобы решить эту проблему, нам нужно указать каталог webappDirectory для подключаемого модуля компрессора и указать ссылку на него в конфигурации подключаемого модуля WAR.
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<nosuffix>true</nosuffix>
<webappDirectory>${project.build.directory}/min</webappDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${project.build.directory}/min</directory>
</resource>
</webResources>
</configuration>
</plugin>
Здесь мы указали каталог min в качестве выходного каталога для минифицированных файлов и настроили подключаемый модуль WAR, чтобы включить его в окончательный вывод.
Теперь у нас есть минифицированные файлы в сгенерированном WAR-файле с их исходными именами файлов foo.js и myCss.css. Мы можем проверить foo.js, чтобы увидеть, что теперь он имеет следующее уменьшенное содержимое:
function testing(){alert("Testing")};
5. Исключение уже уменьшенных файлов
Сторонние библиотеки Javascript и CSS могут иметь уменьшенные версии, доступные для загрузки. Если вам случится использовать один из них в своем проекте, вам не нужно обрабатывать их снова.
Включение уже минифицированных файлов приводит к появлению предупреждающих сообщений при сборке проекта.
Например, jquery-1.11.1.min.js — это уже минимизированный файл Javascript, и во время сборки он вызывает предупреждающие сообщения, подобные приведенным ниже:
[WARNING] .../src/main/webapp/js/jquery-1.11.1.min.js [-1:-1]:
Using 'eval' is not recommended. Moreover, using 'eval' reduces the level of compression!
execScript||function(b){a. ---> eval <--- .call(a,b);})
[WARNING] ...jquery-1.11.1.min.js:line -1:column -1:
Using 'eval' is not recommended. Moreover, using 'eval' reduces the level of compression!
execScript||function(b){a. ---> eval <--- .call(a,b);})
Чтобы исключить уже минимизированные файлы из процесса, настройте подключаемый модуль компрессора с параметром exclude следующим образом:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<nosuffix>true</nosuffix>
<webappDirectory>${project.build.directory}/min</webappDirectory>
<excludes>
<exclude>**/*.min.js</exclude>
</excludes>
</configuration>
</plugin>
Это исключит все файлы во всех каталогах, имена файлов которых заканчиваются на min.js. Выполнение пакета mvn clean теперь не выдает предупреждающих сообщений, и сборка не пытается минимизировать уже минифицированные файлы.
6. Заключение
В этой статье мы описали хороший способ интеграции минификации файлов Javascript и CSS в ваш рабочий процесс Maven. Чтобы обслуживать эти статические ресурсы с помощью приложения Spring MVC, см. нашу статью «Обслуживание статических ресурсов с помощью Spring».
Вы можете найти код этой статьи на GitHub.