Как уменьшить отфильтрованный файл javascript с помощью maven?

#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 file src/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.