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

StackOverflow https://stackoverflow.com/questions/4663686

Вопрос

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

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

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

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

Вместо этого я хотел бы сделать компиляцию JS частью основной (Java) компиляции.Сам компилятор JS (Require JS) загружается как зависимость во время фазы наложения WAR, которая происходит после компиляции.Итак, мне нужно, чтобы файлы Require 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/** чтобы закончить ВОЙНУ, я включаю это как часть наложения, чтобы получить распакованные скрипты сборки RequireJS, просто потому, что я не придумал лучшего способа.

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

        <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-файла, один только с материалами для выполнения, а другой для сценариев компиляции?
  2. Я хотел бы вызвать exec:exec в идеале - во время компиляции, а если нет, то непосредственно перед ВОЕННОЙ упаковкой.Как мне это сделать?

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

Это было полезно?

Решение 3

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

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

Обновить

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

Другие советы

Существует плагин maven, специально предназначенный для оптимизации RequireJS по адресу:

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

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

Полное раскрытие информации:Я написал плагин.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top