Question

J'ai un projet web qui est construit avec Maven et je suis en train de déterminer la meilleure façon de compiler les fichiers JavaScript avec le compilateur RequireJS (cette question pourrait appliquer à tout compilateur / minifier ainsi).

J'ai une configuration qui fonctionne, mais il a besoin d'améliorations:

J'ai empaqueté la 3e partie des bibliothèques JavaScript et ils sont en cours de téléchargement en tant que dépendances, puis ajouté avec le plugin WAR Overlay.

J'ai une tâche du plugin Exec qui exécute le compilateur RequireJS dans la cible . Je suis actuellement exécuter manuellement exec:exec après l'exécution cible de package (et donc le contenu de WAR sont placés dans le répertoire cible).

Ce que je voudrais est au lieu de faire partie de la compilation JS de compilation principale (Java). Le compilateur JS lui-même (JS Exigent) est téléchargée en tant que dépendance au cours de la phase de recouvrement WAR qui se produit après la compilation. Donc, j'ai besoin require fichiers JS à télécharger et déballés et je dois exécuter la compilation JS en utilisant ces fichiers, avant / pendant / après la compilation Java.

Je suis sûr qu'il pourrait y avoir plusieurs façons d'y parvenir. Je cherche la solution la plus élégante.


Mise à jour: extraits existants POM

J'ai dépendances JavaScript que j'ai compressé et ajouté à notre gestionnaire de référentiel:

    <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>

Prenez note que RequireJS lui-même (qui est nécessaire pour la compilation du reste des bibliothèques) est également chargée en tant que dépendance externe. La première chose est, j'ai besoin de cette dépendance à télécharger et décompressé avant que je puisse commencer avec la compilation RequireJS.

Ces dépendances sont ajoutées à la guerre en utilisant le plugin 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>

Même si je ne ai pas besoin requirejs/build/** pour finir dans la guerre, je l'inclure dans le cadre de la superposition pour obtenir les RequireJS décompressés construire des scripts, simplement parce que je ne l'ai pas compris une meilleure façon.

Alors j'ai une tâche de plug-in Exec qui effectue la compilation. Mais notez que cette tâche n'a pas été ajouté au flux de travail de compilation normale: Je dois manuellement avec Invoke mvn exec:exec après l'emballage WAR est fait:

        <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>

Alors, quelques questions sont:

  1. Comment puis-je extraire différentes parties d'une seule dépendance à fermeture éclair pour la compilation et WAR étapes d'emballage? Ou dois-je créer deux fichiers zip, un avec juste les trucs d'exécution et l'autre pour les scripts de compilations?
  2. Je voudrais trigger exec:exec idéalement lors de la compilation, ou sinon, juste avant l'emballage WAR. Comment puis-je faire?

J'ai vraiment essayé un tas de choses sans succès, donc j'espère que je ne semble pas que l'affichage paresseusement un énorme morceau de code et d'attendre des réponses :) Il est juste que je ne l'ai pas tout à fait emballé mon esprit autour de la façon dont Maven objectifs / phases etc. encore le travail.

Était-ce utile?

La solution 3

Je suis venu avec la solution suivante qui fonctionne pour moi:

Au lieu de dépendre de la superposition de WAR pour le déballage des fichiers RequireJS, je les déballer explicitement à l'aide du plug-in Dépendance:

  <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>

La phase est réglée sur « compilation ». Cela me permet d'avoir le contenu du paquet RequireJS dans le dossier « dépendance », lors de la compilation. Alors, la prochaine chose que j'est:

      <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>

Cela déclenche la compilation dans le dossier « dépendance », sans toucher mon répertoire source ou le répertoire WAR. Je continue puis en utilisant le plugin overlay WAR cerise choisir les fichiers RequireJS qui veulent entrer dans la guerre.

Mise à jour

Depuis la rédaction de cette solution, je l'ai commencé à utiliser la « java » but au lieu de « exec » parce que j'avais des problèmes avec l'aide du script shell de compilateur RequireJS + fichier batch par Hudson. Je suis essentiellement exécutant la commande Java final (généré par les scripts) qui exécutent le compilateur par Rhino. La solution de nœud serait légèrement différent. Pour RequireJS 0.23.0, il va quelque chose comme ceci:

<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>

Autres conseils

Il y a un plugin maven spécifiquement ciblé pour l'optimisation RequireJS à:

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

Il est toujours livré avec une version récente de RequireJS, et il est assez facile de passer outre que l'ajout d'une version différente de votre projet, et en spécifiant chemin de dans la configuration plug-in.

La divulgation complète:. J'ai écrit le plug-in

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top