2011-01-11 7 views
19

У меня есть веб-проект, который построен с Maven, и я пытаюсь найти лучший способ скомпилировать файлы JavaScript с помощью компилятора RequireJS (этот вопрос может применяться к любому компилятору/минерал).RequireJS Компиляция в проекте Maven с внешними зависимостями JS

У меня есть установка, которая работает, но она нуждается в улучшении:

Я упакована в 3-й партии библиотеки JavaScript, и они загружаются в качестве зависимостей, а затем добавил с плагином WAR Overlay.

У меня есть задача плагина Exec, которая запускает компилятор RequireJS внутри целевого каталога. В настоящий момент я запускаю вручную exec:exec после запуска целевого объекта (и поэтому содержимое WAR помещается в целевой каталог).

Я хотел бы вместо этого сделать компиляцию JS части основной (Java) компиляции. Сам компилятор JS (Require JS) загружается как зависимость во время фазы наложения WAR, которая происходит после компиляции. Поэтому мне нужно, чтобы требуемые файлы JS загружались и распаковывались, и мне нужно запускать компиляцию JS с использованием этих файлов до/во время/после компиляции Java.

Я уверен, что может быть несколько способов достичь этого. Я ищу наиболее элегантное решение.


Обновление: Существующие фрагменты POM

У меня есть зависимости JavaScript, которые я заархивированы и добавлен в наш репозиторий менеджер:

<dependency> 
     <groupId>org.requirejs</groupId> 
     <artifactId>requirejs</artifactId> 
     <version>0.22.0</version> 
     <classifier>repackaged</classifier> 
     <type>zip</type> 
     <scope>runtime</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.jqueryui</groupId> 
     <artifactId>jquery-ui</artifactId> 
     <version>1.8.7</version> 
     <classifier>repackaged</classifier> 
     <type>zip</type> 
     <scope>runtime</scope> 
    </dependency> 

принять к сведению, что RequireJS себя (что необходимо для компиляция остальных библиотек) также загружается как внешняя зависимость. Итак, во-первых, мне нужно, чтобы эта зависимость загружалась и распаковывалась, прежде чем я начну с компиляции RequireJS.

Эти зависимости добавляются в WAR с помощью плагина WAR Overlay:

 <plugin> 
      <artifactId>maven-war-plugin</artifactId> 
      <configuration> 
       <overlays> 
        <overlay> 
         <groupId>org.requirejs</groupId> 
         <artifactId>requirejs</artifactId> 
         <classifier>repackaged</classifier> 
         <type>zip</type> 
         <targetPath>lib</targetPath> 
         <includes> 
          <include>requirejs/require.js</include> 
          <include>requirejs/require/*</include> 
          <include>requirejs/build/**</include> 
         </includes> 
        </overlay> 
        <overlay> 
         <groupId>com.jqueryui</groupId> 
         <artifactId>jquery-ui</artifactId> 
         <classifier>repackaged</classifier> 
         <type>zip</type> 
         <targetPath>lib</targetPath> 
        </overlay> 
       </overlays> 
      </configuration> 
     </plugin> 

Даже если мне не нужно requirejs/build/** закончить в WAR, я в том числе его как часть наложения чтобы получить распакованные скрипты сборки RequireJS, просто потому, что я не понял лучшего способа.

Тогда у меня есть задача плагина Exec, которая выполняет компиляцию. Но обратите внимание, что эта задача не была добавлена ​​к обычному потоку компиляции работы: я должен вручную вызвать его с mvn exec:execпосле упаковки WAR сделано:

 <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>exec-maven-plugin</artifactId> 
      <version>1.1</version> 
      <executions> 
       <execution> 
        <goals> 
         <goal>exec</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <executable>lib/requirejs/build/build.bat</executable> 
       <workingDirectory>${project.build.directory}/${project.artifactId}</workingDirectory> 
       <arguments> 
        <argument>name=bootstrap</argument> 
        <argument>out=combined.js</argument> 
        <argument>baseUrl=scripts</argument> 
        <argument>optimize=closure</argument> 
        <argument>excludeShallow=plugins/manifest</argument> 
       </arguments> 
      </configuration> 
     </plugin> 

Так, некоторые вопросы:

  1. Как я могу извлечь разные части одной заархивированной зависимости для шагов сборки компиляции и WAR? Или мне нужно создать два zip-файла, один с файлом runtime, а другой для скриптов компиляции?
  2. Я хотел бы включить exec:exec в идеале во время компиляции, а если нет, перед упаковкой WAR. Как мне это сделать?

Я действительно пробовал кучу вещей без успеха, поэтому я надеюсь, что я не буду лениво размещать огромный кусок кода и ждать ответов :) Это просто, что я не совсем завернул свой разум вокруг того, как цели/фазы Maven работают еще.

+0

Возможно, вы сможете разместить соответствующий фрагмент pom? – Raghuram

+0

@ Raghuram: Выполнено. –

ответ

4

Я придумал следующее решением, которое работает для меня:

Вместо зависимости от WAR накладки для распаковки файлов RequireJS, я явно распаковывать их с помощью плагина зависимостей:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-dependency-plugin</artifactId> 
    <executions> 
     <execution> 
     <phase>compile</phase> 
     <goals> 
      <goal>unpack</goal> 
     </goals> 
     <configuration> 
      <artifactItems> 
      <artifactItem> 
       <groupId>org.requirejs</groupId> 
       <artifactId>requirejs</artifactId> 
       <version>0.22.0</version> 
       <type>zip</type> 
       <classifier>repackaged</classifier> 
       <overWrite>true</overWrite> 
      </artifactItem> 
      </artifactItems> 
     </configuration> 
     </execution> 
    </executions> 
    </plugin> 

Фаза настроена на «компиляцию». Это позволяет мне во время компиляции загрузить содержимое пакета RequireJS в папку «dependency». Итак, следующая вещь, у меня есть:

 <plugin> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>exec-maven-plugin</artifactId> 
     <version>1.1</version> 
     <executions> 
      <execution> 
      <phase>compile</phase> 
      <goals> 
       <goal>exec</goal> 
      </goals> 
      <configuration> 
       <executable> 
       ${project.build.directory}/dependency/requirejs/build/build.bat</executable> 
       <workingDirectory> 
       ${basedir}/src/main/webapp</workingDirectory> 
       <arguments> 
       <argument>name=bootstrap</argument> 
       <argument>out=scripts/compiled.js</argument> 
       <argument>baseUrl=scripts</argument> 
       <argument>optimize=closure</argument> 
       <argument> 
       excludeShallow=plugins/manifest</argument> 
       </arguments> 
      </configuration> 
      </execution> 
     </executions> 
     </plugin> 

Это вызывает RequireJS компиляции в папке «зависимости», не касаясь ни моего исходный каталог или каталог WAR. Затем я продолжаю использовать плагин WAR overlay для вишни, чтобы выбрать файлы RequireJS, которые хотят войти в WAR.

Update

С момента написания этого решения, я перешел на использование «Java» цели вместо «Exec», потому что у меня были проблемы с использованием файла оболочки сценария + пакетное в RequireJS компилятора через Гудзон. Я в основном запускаю последнюю команду Java (сгенерированную скриптами), которая запускает компилятор через Rhino. Решение узла будет немного отличаться. Для RequireJS 0.23.0, он идет что-то вроде этого:

<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>exec-maven-plugin</artifactId> 
    <version>1.1</version> 
    <executions> 
     <execution> 
      <id>compile-js</id> 
      <phase>compile</phase> 
      <goals> 
       <goal>exec</goal> 
      </goals> 
      <configuration> 
       <executable>java</executable> 
       <workingDirectory>${basedir}/src/main/webapp</workingDirectory> 
       <arguments> 
        <argument>-classpath</argument> 
        <!--argument>${project.build.directory}/dependency/requirejs/build/lib/rhino/js.jar${path.separator}${project.build.directory}/dependency/requirejs/build/lib/closure/compiler.jar</argument --> 
        <argument>${project.build.directory}/dependency/requirejs/build/lib/rhino/js.jar</argument> 
        <argument>org.mozilla.javascript.tools.shell.Main</argument> 
        <argument>${project.build.directory}/dependency/requirejs/bin/x.js</argument> 
        <argument>${project.build.directory}/dependency/requirejs/bin/</argument> 
        <argument>${project.build.directory}/dependency/requirejs/build/build.js</argument> 
        <argument>name=bootstrap</argument> 
        <argument>out=scripts/compiled.js</argument> 
        <argument>baseUrl=scripts</argument> 
        <argument>optimize=none</argument> 
       </arguments> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 
+0

Это пытается запустить узел, поэтому я получаю сообщение об ошибке при выполнении компилятора. Узел не должен быть требованием для компилятора requirejs, нет? – adam

+0

@adam: Это было с RequireJS 0.22.0. Вы попробовали это с 0.23.0? Сценарии сборки существенно различаются между ними. –

+0

Да, я использовал 0.23.0, который выполняет команду node в build.bat или в любом случае .bat он выполняет – adam

8
+0

Я переместил это в https://github.com/jakewins/brew, который добавляет поддержку для компиляции coffeescript и haml шаблоны. В плагин для пива есть некоторые исправления, которые недоступны в requirejs-maven. Brew по-прежнему нестабилен, но активно развивается и используется в производстве. – jakewins

6

Там в Maven плагин, специально предназначенные для оптимизации RequireJS на:

https://github.com/mcheely/requirejs-maven-plugin

Оно всегда должно поставляться с недавняя версия RequireJS, и довольно легко переопределить это, добавив в проект другую версию и указав ее путь в конфигурации плагина.

Полное раскрытие: я написал плагин.

+0

Эй! Я попробую это ... –

+0

Это отлично работает, если проект является автономным, но он не работает, если мы потянемся через оверлей плагина maven-war-plugin (по вопросу OP) - не так ли? –