Tuesday, September 03, 2013

Play2 javascript library dependencies

Play2 javascript library dependencies

Dependency management problem

It's common practice in java domain to rely on dependency management infrastructures like Apache Maven. As one starts to develop html app's with various javascript libraries it's necessary to manually copy files and adjust paths, which is error prone. In maven you would do this by changing single line, but now instead of changing version number on one file quite a lot simple manual operations are needed.

Asset management on Play2

Javascript libraries are used on html pages, which means they are carried to client over http as requested by browser. On server side resides mapping from http Url to location of requested resource on servers disk.

Play2 serves static assets from Public directory using Assets controller. This mechanism is defined at conf/routes file.


# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)

Webjars is library which makes it possible to serve static content from jars which are acquired thru Apache IVY dependency management.

When your container, web framework, or application needs to serve static assets from Jar files webJar needs to be a dependency of your application.

Defining Play2 dependencies

Please select which webjars-play fits to Play2 version in use, then add to project/build.scala needed dependencies for webjars.

  val appDependencies = Seq(
    "org.webjars" %% "webjars-play" % "2.1.0-3",

and for components you use
  • "org.webjars" % "jquery" % "2.0.3",
  • "org.webjars" % "bootstrap" % "3.0.0",

Serving static content from jars

To serve static content from jars one needs to add route to files. Here's example you can use

conf/routes

# Map static resources from the jar packages to the /webjars URL path
GET     /webjars/*file controllers.WebJarAssets.at(file)

Fetching static content from webjars

As all references to libraries used are already collected to single template file we just need to use /webjars Url instead of /public when getting required libs.

Main template view is at app/views/main.scala.html, and here one need to comment out static content and enable webjars content.

        @* no more direct static jquery from /public *@
        @* <script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script> *@
        
        @* resources thru /webjars *@        
        <link rel='stylesheet' href='@routes.WebJarAssets.at(WebJarAssets.locate("css/bootstrap.min.css"))'>
<script type='text/javascript' src='@routes.WebJarAssets.at(WebJarAssets.locate("jquery.min.js"))'></script>

Test changes

Main template is getting content element as optional variable.

@(title: String)(content: Html)

You can now wrap content inside Twitter bootstraps container using class container.

    <div class="container">
           @content
     </div>


Summary

Dependency management for javascript makes it easier to work together in teams when it's possible from build definitions to see which versions of javascript libraries are in use and they can be changed once for all developers thru shared dependency management mechanism. 

Example of Webjars usage where listed steps have been committed can be seen here

https://github.com/nikkijuk/smooks-play2-xml-to-jpa

No comments: