dependencies maven javascript requirejs

dependencies - RequireJS Compilation en el proyecto Maven con dependencias JS externas



javascript (3)

Tengo un proyecto web creado con Maven y estoy tratando de descubrir la mejor manera de compilar los archivos JavaScript con el compilador RequireJS (esta pregunta también podría aplicarse a cualquier compilador / minificador).

Tengo una configuración que funciona, pero necesita mejoras:

He empaquetado las bibliotecas de JavaScript de terceros, se están descargando como dependencias y luego se agregan con el complemento WAR Overlay.

Tengo una tarea del complemento Exec que ejecuta el compilador RequireJS dentro del directorio de destino . Actualmente ejecuto manualmente exec:exec después de que se ejecute el paquete de destino (y, por lo tanto, los contenidos WAR se colocan en el directorio de destino).

Lo que me gustaría en cambio es que la compilación JS sea parte de la compilación principal (Java). El propio compilador JS (Require JS) se descarga como una dependencia durante la fase de superposición WAR que ocurre después de la compilación. Por lo tanto, necesito que los archivos Require JS se descarguen y desempaqueten y necesito ejecutar la compilación JS utilizando esos archivos, antes / durante / después de la compilación Java.

Estoy seguro de que podría haber varias maneras de lograr esto. Estoy buscando la solución más elegante.

Actualización: Fragmentos POM existentes

Tengo dependencias de JavaScript que he comprimido y agregado a nuestro administrador de repositorios:

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

Tenga en cuenta que RequireJS en sí (que es necesario para la compilación del resto de bibliotecas) también se carga como una dependencia externa. Entonces, lo primero es que necesito que se descargue y descomprima esta dependencia antes de poder comenzar con la compilación de RequireJS.

Estas dependencias se están agregando al WAR mediante el complemento 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>

Aunque no necesito requirejs/build/** para terminar en WAR, lo incluyo como parte de la superposición para obtener los scripts de construcción RequireJS descomprimidos, simplemente porque no he descubierto una mejor manera.

Luego tengo una tarea del complemento Exec que realiza la compilación. Pero tenga en cuenta que esta tarea no se ha agregado al flujo de trabajo de compilación normal: tengo que invocarlo manualmente con mvn exec:exec después de que se haya completado el empaquetado 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>

Entonces, algunas preguntas son:

  1. ¿Cómo puedo extraer diferentes partes de una única dependencia comprimida para los pasos de compilación y empaquetado WAR? ¿O tengo que crear dos archivos zip, uno con solo el tiempo de ejecución y el otro para los scripts de compilación?
  2. Me gustaría activar exec:exec idealmente durante la compilación, o si no, justo antes del empaquetado WAR. ¿Cómo puedo hacer eso?

De hecho, he intentado un montón de cosas sin éxito, así que espero que no parezca que publique perezosamente un gran trozo de código y que espere respuestas :) Es solo que no he enfocado mi mente en cómo los objetivos / fases de Maven trabajo todavía.


Hay un complemento de Maven específicamente diseñado para la optimización RequireJS en:

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

Siempre debe incluir una versión reciente de RequireJS, y es bastante fácil anularlo agregando una versión diferente a su proyecto y especificando su ruta en la configuración del complemento.

Revelación completa: escribí el plugin.


Se me ha ocurrido la siguiente solución que me funciona:

En lugar de depender de la superposición WAR para el desempaquetado de los archivos RequireJS, los descomprimo explícitamente utilizando el complemento de dependencia:

<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 fase está configurada para "compilar". Esto me permite tener todo el contenido del paquete RequireJS en la carpeta "dependencia", durante la compilación. Entonces, lo siguiente que tengo es:

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

Esto activa la compilación de RequireJS dentro de la carpeta "dependencia", sin tocar el directorio de origen ni el directorio WAR. Luego continúo usando el complemento de superposición WAR para seleccionar los archivos RequireJS que desean ingresar en WAR.

Actualizar

Desde que escribí esta solución, cambié a usar el objetivo "java" en lugar de "exec" porque tuve problemas con el uso del script de compilación de RequireJS + archivo por lotes a través de Hudson. Básicamente, estoy ejecutando el comando Java final (generado por los scripts) que ejecuta el compilador a través de Rhino. La solución de Nodo sería ligeramente diferente. Para RequireJS 0.23.0, es algo como esto:

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