#javascript #maven #filter #minify
#javascript #maven #Фильтр #минимизировать
Вопрос:
У меня есть файл javascript, который используется для отслеживания событий с помощью Google Analytics. Я создал разные учетные записи для промежуточной и производственной среды. В скрипте для вызова кода GA есть место для идентификатора моей учетной записи. Идентификаторы учетных записей были указаны в файлах фильтра. Используя элемент webResources в плагине maven-war, мы можем успешно заменить свойство в конечном файле WAR.
Теперь мы также используем плагин maven-yuicompressor для минимизации и агрегирования всех наших файлов javascript. Проблема в том, что если я присоединяю выполнение minify goal к фазе пакета, WAR создается до того, как Javascript был минимизирован. Если я прикреплю цель минимизации к чему-либо ранее, фильтр не применялся до момента минимизации, создавая недопустимый файл.
Итак, я ищу способ запустить minify goal между плагином WAR, копирующим отфильтрованные файлы JS и создающим файл WAR. Вот соответствующие части моего pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp/js</directory>
<targetPath>js</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<linebreakpos>-1</linebreakpos>
<nosuffix>true</nosuffix>
<force>true</force>
<aggregations>
<aggregation>
<output>${project.build.directory}/${project.build.finalName}/js/mysite-min.js</output>
<inputDir>${project.build.directory}/${project.build.finalName}/js</inputDir>
<includes>
<include>jquery-1.4.2.js</include>
<include>jquery-ui.min.js</include>
<include>ga-invoker.js</include>
</includes>
</aggregation>
</aggregations>
</configuration>
</plugin>
Комментарии:
1. Может быть, привязать его к
prepare-package
?2. Как я упоминал ранее, присоединение к чему-либо до фазы пакета не работает, поскольку фильтр до этого не применялся. Плагин war копирует веб-ресурсы и применяет фильтр как часть самой фазы пакета.
Ответ №1:
Отличный вопрос, отличный ответ от artbristol, за который я проголосовал. Это мне очень помогло. Для дальнейшего использования я публикую полное решение:
- Поместите ваши файлы Javascript в
src/main/resources/js
(или во что угодно, что соответствует вашим потребностям) - Поместите ваши CSS-файлы в
src/main/resources/css
(или во что угодно, что соответствует вашим потребностям) - Плагин Resources фильтрует ваши ресурсы javascript и копирует их в
target/classes/js/
- Yui собирает файлы в target / classes / js / и объединяет их в
src/main/webapp
- Вы можете протестировать свои настройки с помощью
jetty:run
. Jetty собирает сжатые и агрегированные файлы вsrc/main/webapp
- плагин war на этапе упаковки собирает ваши файлы под
src/main/webapp
- необязательно помещать в SCM игнорируемый файл типа
.svnignore
или.cvsignore
filesrc/main/webapp
для исключенияall.js
из вашего любимого инструмента SCM.
Раздел excludes необходим, чтобы избежать сжатия чего-либо в src / main /resources и src /main /webapp. yui должен просто собирать уже отфильтрованные файлы для агрегации.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>*/*</exclude>
</excludes>
<force>true</force>
<nosuffix>true</nosuffix>
<removeIncluded>true</removeIncluded>
<aggregations>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.basedir}/src/main/webapp/js/all.js</output>
<includes>
<include>${project.build.directory}/classes/js/file1.js</include>
<include>${project.build.directory}/classes/js/file2.js</include>
</aggregation>
<aggregation>
<insertNewLine>true</insertNewLine>
<output>${project.basedir}/src/main/webapp/css/all.css</output>
<includes>
<include>${project.build.directory}/classes/css/file1.css</include>
<include>${project.build.directory}/classes/css/file2.css</include>
</aggregation>
</aggregations>
</configuration>
</plugin>
Зачем вам нужна фильтрация файлов css?
я использую его для ссылки на мои изображения следующим образом
div.header {
background-image: url(/img/background.${project.version}.png)
}
Maven фильтрует версию моего проекта в моих файлах css. Любой входящий запрос на нашем сервере изображений фильтруется следующим образом
protected void doHttpFilter ( HttpServletRequest request, HttpServletResponse response, FilterChain chain ) throws IOException, ServletException
{
String uri = request.getRequestURI();
if (isStaticRequest(uri))
{
String uriWithoutVersion = stripVersionString(uri);
String versionRequested = getVersionString(uri);
if (version.equals(versionRequested))
{
response.setHeader(CACHE_CONTROL_HEADER_NAME, CACHE_CONTROL_HEADER_VALUE);
response.setHeader(EXPIRES_HEADER_NAME, EXPIRES_HEADER_VALUE);
}
RequestDispatcher dispatcher = request.getRequestDispatcher(uriOhneVersionsnummer);
dispatcher.forward(request, response);
} else {
chain.doFilter(request, response);
return;
}
}
таким образом, браузер кэширует каждый файл навсегда. но когда я загружаю новую версию, все ссылки на файлы имеют новый номер версии, поэтому браузер снова извлекает изображение или css.
это очень помогло нам сократить трафик.
Ответ №2:
Можете ли вы поместить отфильтрованные файлы js в src /main/resources /filtered-js, вместо этого использовать плагин resources, который привязывается к process-resources
, затем указать конфигурацию webresources плагина maven-war на target/classes/filtered-js
?
Комментарии:
1. Вы опередили меня в публикации ответа. Вчера я делал нечто подобное. Я позволил плагину yuicompressor оставаться подключенным к фазе process-resources, которая используется по умолчанию, но настроил его вывод на переход к target / js. Затем я использовал конфигурацию webResources плагина maven-war для фильтрации содержимого этого каталога и поместил их в target /<build. имя_финала>/js. Все равно нужно пометить свой ответ как правильный.
Ответ №3:
Я использую плагин Maven Minify для сжатия файлов javascript и css. Он также объединяет эти файлы в один файл.Это работает нормально
Я использовал плагин maven-timestamp, чтобы добавить к этому файлу суффикс unque в качестве решения для кэша браузера.Это тоже работает нормально
То, с чем я застрял, — это как заменить все ссылки на js и css на те, которые были созданы во время выполнения сборки.
Я смотрю в maven-replace-plugin для того же. Он может удалить все экземпляры.Он может быть заменен новыми значениями. Но мне нужно сохранить один экземпляр недавно объединенных-уменьшенных js и css.
<plugins>
<plugin>
<groupId>com.keyboardsamurais.maven</groupId>
<artifactId>maven-timestamp-plugin</artifactId>
<version>1.0</version>
<configuration>
<propertyName>timestamp</propertyName>
<timestampPattern>ddMMyyyyHHmm</timestampPattern>
</configuration>
<executions>
<execution>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/resources/themes</outputDirectory>
<resources>
<resource>
<includes>
<include>**/*.vm</include>
</includes>
<directory>${basedir}/src/main/resources/themes</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.samaxes.maven</groupId>
<artifactId>maven-minify-plugin</artifactId>
<version>1.3.5</version>
<executions>
<execution>
<id>default-minify</id>
<phase>process-resources</phase>
<configuration>
<cssSourceDir>../resources/themes/XXXX/default/template-resources/stylesheet</cssSourceDir>
<cssSourceIncludes>
<cssSourceInclude>**/*.css</cssSourceInclude>
</cssSourceIncludes>
<cssFinalFile>style.css</cssFinalFile>
<jsSourceDir>../resources/themes/XXXX/default/template-resources/js</jsSourceDir>
<jsSourceIncludes>
<jsSourceInclude>*.js</jsSourceInclude>
</jsSourceIncludes>
<jsSourceFiles>
<jsSourceFile>/libs/json.js</jsSourceFile>
</jsSourceFiles>
<jsFinalFile>script.js</jsFinalFile>
<suffix>-${timestamp}</suffix>
</configuration>
<goals>
<goal>minify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>target/resources/themes/XXXX/default/templates/velocity/**/*.vm</include>
</includes>
<replacements>
<replacement>
<token><![CDATA[<link rel="stylesheet" href="/storefront/template-resources/stylesheet/]]>([a-zA-Z0-9-_]*.css)<![CDATA[" type="text/css"/>]]>([])</token>
<value></value>
</replacement>
<replacement>
<token><![CDATA[<link rel="stylesheet" href="/storefront/template-resources/stylesheet/powerreviews]]>([a-zA-Z0-9-_]*.css)<![CDATA[" type="text/css"/>]]></token>
<value></value>
</replacement>
<replacement>
<token><![CDATA[<script type="text/javascript" src="/storefront/template-resources/js/]]>([a-zA-Z0-9-_.]*.js)<![CDATA["></script>]]></token>
<value></value>
</replacement>
<replacement>
<token><![CDATA[<script type="text/javascript" src="/storefront/template-resources/js/libs/]]>([a-zA-Z0-9-_.]*.js)<![CDATA["></script>]]></token>
<value></value>
</replacement>
</replacements>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>dist</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Комментарии:
1. для очистки кэша вы можете захотеть использовать контрольные суммы MD5, а не временные метки. С временными метками ваш кэш будет недействительным каждый раз, когда вы выполняете сборку, независимо от того, меняете ли вы JS и CSS.