Подтвердить что ты не робот

Компиляция RequireJS в проекте Maven с внешними зависимостями JS

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

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

Я упаковал сторонние библиотеки 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>

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

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

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

4b9b3361

Ответ 1

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

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

  <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 внутри папки "dependency", не затрагивая ни мою исходную директорию, ни каталог WAR. Затем я продолжаю использовать плагин WAR overlay для вишни, чтобы выбрать файлы RequireJS, которые хотят войти в WAR.

Обновление

С момента написания этого решения я переключился на использование цели "java" вместо "exec", потому что у меня были проблемы с использованием оболочки компилятора RequireJS script + пакетного файла через Hudson. Я в основном запускаю последнюю команду Java (сгенерированную скриптами), которая запускает компилятор через Rhino. Решение Node будет немного отличаться. Для 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>

Ответ 3

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

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

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

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