Компиляция RequireJS в проекте Maven с внешними зависимостями JS - PullRequest
19 голосов
/ 12 января 2011

У меня есть веб-проект, созданный с помощью 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/**, чтобы оказаться в 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-файла, один из которых содержит только среду выполнения, а другой - для сценариев компиляции?
  2. Я хотел бы вызвать exec:exec в идеале во время компиляции или, если нет, непосредственно перед упаковкой WAR. Как мне это сделать?

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

Ответы [ 3 ]

8 голосов
/ 23 февраля 2011
6 голосов
/ 19 июля 2012

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

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

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

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

4 голосов
/ 19 января 2011

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

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

Обновление

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