❮ zur Übersicht

Sass support for web applications with jetty and wro4j

  • Autor: messner
  • Datum: 26.05.2014

Suppose we voted for Sass as the css preprocessor of our choice for a web application. Knowing that css must be generated from our Sass code everytime a scss file is modified, we want to set up the project in a way that enables fast turnaround cycles during development.

The Requirements are:

  • generated css should be bundled within the WAR when building the webapp for production on the continuous integration server

  • changes made to Sass resources during development time should be available to the browser without requiring a rebuild of the webapp

One way to fit these requirements is to use Jetty and the Web Resource Optimizer for Java. wro4j provides Sass support with the JRuby based RubySassCssProcessor which can be used both as a pre or post processor. In order to compile our scss into css when building the webapp we have to include the wro4j-maven-plugin into the projects POM:

<plugin>
  <groupid>ro.isdc.wro4j</groupid>
  <artifactid>wro4j-maven-plugin</artifactid>
  <version>${wro4jversion}</version>
  <configuration>
    <wromanagerfactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wromanagerfactory>
    <cssdestinationfolder>${project.build.directory}/${project.build.finalName}/css/</cssdestinationfolder>
  </configuration>
  <executions>
    <execution>
      <phase>prepare-package</phase>
      <goals>
        <goal>run</goal>
      </goals>
    </execution>
  </executions>
</plugin>

The plugins run goal is bound to the prepare-package phase, so the WAR will contain the css resource in /css/ after packaging the web application. In addition to the plugin configuration we also have to provide some merging and pre/post processor related configuration settings in wro.xml and wro.properties respectively.

wro.xml

<groups xmlns="http://www.isdc.ro/wro">
  <group name="base">
    <css>/sass/base/*.scss</css>
  </group>
</groups>

wro.properties

managerFactoryClassName=ro.isdc.wro.manager.factory.ConfigurableWroManagerFactory
preProcessors=cssUrlRewriting
postProcessors=rubySassCss,cssMinJawr
disableCache=true

The configuration settings for caching and the manager factory are necessary for development environment: at development time we want a servlet filter to trigger the css compilation process every time when the browser requests the css.

To enable this mechanism we place the file override-web.xml in directory src/test/resources/

override-web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xmlns="http://java.sun.com/xml/ns/javaee">
  <filter>
    <filter-name>wro</filter-name>
    <filter-class>ro.isdc.wro.http.WroFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>wro</filter-name>
    <url-pattern>*.css</url-pattern>
  </filter-mapping>
</web-app>

override-web.xml is a web.xml that Jetty applies to a web application after the application’s own WEB-INF/web.xml which means that it can override values or add new elements. The jetty-maven-plugin allows to configure the location of that file with the overridedescriptor tag:

pom.xml

<plugin>
  <groupid>org.eclipse.jetty</groupid>
  <artifactid>jetty-maven-plugin</artifactid>
  <version>9.2.0.RC0</version>
  <configuration>
    <webapp>
      <overridedescriptor>${project.basedir}/src/test/resources/override-web.xml</overridedescriptor>
    </webapp>
  </configuration>
  <dependencies>
    <dependency>
      <groupid>ro.isdc.wro4j</groupid>
      <artifactid>wro4j-core</artifactid>
      <version>${wro4jversion}</version>
    </dependency>
    <dependency>
      <groupid>ro.isdc.wro4j</groupid>
      <artifactid>wro4j-extensions</artifactid>
      <version>${wro4jversion}</version>
    </dependency>
  </dependencies>
</plugin>

Finally we configure the build to exclude Sass resources and wro4j configuration from the WAR:

pom.xml

<plugin>
  <artifactid>maven-war-plugin</artifactid>
  <configuration>
    <warsourceexcludes>
        WEB-INF/wro.*,
        sass/**
    </warsourceexcludes>
  </configuration>
</plugin>

That’s it. With this setup developers are now able to modify scss files and see the resulting css just by reloading the page in the browser.

webapp project structure projectstructure

Tags: Jetty Maven Sass wro4j