Presenting in SF: sbt-web & Reactive All the Way Down

This week I will be presenting twice in San Francisco at SF Scala:

  • Thursday April 10: Introducing sbt-web – A Node & WebJar Compatible Asset Pipeline for the Typesafe Platform

    sbt-web is a new web asset pipeline for Play Framework and other sbt-based frameworks. It can pull dependencies from both Node and WebJars. The pipeline covers all of the phases of client-side development, including: linting, compiling (CoffeeScript, LESS, etc), minification, concatenation, fingerprinting, and gzipping. This session will give you an introduction to sbt-web and show you how to get started using it.

  • Friday April 11: Reactive All the Way Down

    The world is going Reactive but not just for the back-end; UIs are also becoming Reactive. In this session we will walk through how to build an end-to-end Reactive application with Scala, Play Framework, Akka, and AngularJS.

Hope to see you there!

Posted in Play Framework, Reactive, WebJars | Leave a comment

Scala and Vaadin Webinar

On Monday March 24th I will be co-presenting a Webinar about Scala and Vaadin. In this Webinar you will learn how to create great looking web UIs with Vaadin and Scala. No prior Scala experience is necessary. We will start with the basics. Hope to see you there!

Posted in Scala | Leave a comment

WebJars Now on the jsDelivr CDN

WebJars were created to work well with Content Deliver Networks (CDNs) and now thanks to jsDelivr there is a great public CDN hosting all of the WebJar assets! jsDelivr is “a free super-fast CDN for developers and webmasters.” What a perfect match for WebJars!

Here is how it works… Just prefix //cdn.jsdelivr.net in front of your WebJar asset URLs. That’s it! For instance, if the URL you setup to jquery.js is /webjars/jquery/2.1.0/jquery.js then to use the jsDelivr CDN the URL would be: //cdn.jsdelivr.net/webjars/jquery/2.1.0/jquery.js

Because I’m on planes a lot and sometimes have flaky internet, I still like to use my local WebJar assets when doing development. But when I’m running in production I want to switch my apps to pull the WebJar assets from the CDN. Luckily this is now really easy to setup. Here is how you would do it with Play Framework.

Step 1) Create a new controller in controllers/StaticWebJarAssets.scala containing:

package controllers
 
import play.api.mvc.Controller
import play.api.Play
import play.api.Play.current
 
object StaticWebJarAssets extends Controller {
 
  def at(file: String) = Assets.at("/META-INF/resources/webjars", file)
 
  def getUrl(file: String) = {
    val maybeContentUrl = Play.configuration.getString("contentUrl")
 
    maybeContentUrl.map { contentUrl =>
        contentUrl + controllers.routes.StaticWebJarAssets.at(file).url
    } getOrElse controllers.routes.StaticWebJarAssets.at(file).url
  }
 
}

This wrapper around Play’s Assets controller enables setting a contentUrl config parameter that turns the CDN on and off for this app.

Step 2) Update the conf/routes file to use this new controller for WebJar requests:

GET     /webjars/*file                    controllers.StaticWebJarAssets.at(file)

Step 3) Change the server-side templates to use the new StaticWebJarAssets.getUrl reverse routing wrapper so that the URLs in a page change based on the configuration. For example:

<link rel='stylesheet' href='@StaticWebJarAssets.getUrl(WebJarAssets.locate("css/bootstrap.min.css"))'>
<script type='text/javascript' src='@StaticWebJarAssets.getUrl(WebJarAssets.locate("jquery.min.js"))'></script>

Step 4) In the conf/application.conf file set the contentUrl config parameter, like:

contentUrl="//cdn.jsdelivr.net"

This will make your local development environment use the CDN. Instead you can just set this in your production config. The webjars.org site uses the following config:

contentUrl=${?CONTENT_URL}

This syntax sets the contentUrl config if a CONTENT_URL environment variable is present, otherwise it does not set it.

That is all I had to do to move the static asset handling for webjars.org to the jsDelivr CDN! Pretty awesome stuff.

A big huge thank you to jsDelivr and Dmitriy Akulov (who works for MaxCDN) for stepping up to help out WebJars!!! I emailed Dmitriy out-of-the-blue not expecting that they’d would be interested in helping WebJars but he quickly responded and helped me get everything setup in a matter of hours! With that kind of service I’m definitely looking into the MaxCDN services for my non-open source projects.

Posted in WebJars | 5 Responses

Presenting Building Reactive Apps in Denver

This Thursday (March 20, 2014) I will be presenting Building Reactive Apps at the Reactive Programming Enthusiasts Denver.

Here is the session description:

Non-blocking, asynchronous, and reactive programming models are all the rage today. This session will explore in-depth why these patterns are important in modern apps. We will drill down and see how to apply them to event-driven web, mobile, and RESTful apps. To illustrate the concepts, we will use Java, Scala, Akka, and the Play Framework as examples.

Hope to see you there!

Posted in Reactive | Leave a comment

Official Support for RequireJS in WebJars

WebJars Locator now has direct support for RequireJS! For a while the WebJars Play helper library has had support for RequireJS which was great but it had a few issues and wasn’t useful outside of Play.

There is now a org.webjars.RequireJS.getSetupJavaScript(String webjarUrlPrefix) method that produces the RequireJS configuration for the WebJars you are using. If you are using only the jQuery WebJar then that JavaScript configuration looks like:

var webjars = {
    versions: { 'requirejs': '2.1.10', 'jquery': '2.1.0' },
    path: function(webjarid, path) {
        return '/webjars/' + webjarid + '/' + webjars.versions[webjarid] + '/' + path;
    }
};
 
var require = {
    callback: function() {
        // no-op webjars requirejs plugin loader for backwards compatibility
        define('webjars', function () {
            return { load: function (name, req, onload, config) { onload(); } }
        });
 
        // all of the webjar configs from their webjars-requirejs.js files
 
        // webjar config for jquery
        requirejs.config({
            paths: { "jquery": webjars.path("jquery", "jquery") },
            shim: { "jquery": { "exports": "$" } }
        });
    }
}

This sets up the paths for RequireJS modules in WebJars and pulls in any other custom configuration from the WebJar’s RequireJS config. To use this setup JavaScript with RequireJS you can add something like the following to your web page:

<script>
// the following includes the setup JavaScript directly in the page
// (in this case using Play's server-side templating)
@Html(org.webjars.RequireJS.getSetupJavaScript("/webjars/"))
 
// alternatively you can create a controller that returns the JavaScript
// and then use a src="blah" to load the setup JavaScript
</script>
 
<!-- The following can use the WebJars Locator to avoid hard-coding the full path -->
<script data-main="/assets/index" src="/webjars/requirejs/2.1.10/require.min.js"></script>

The WebJars Play library now has a new helper that wraps all that up into a nice function:

@Html(org.webjars.play.RequireJS.setup("index"))

That loads the setup JavaScript and loads RequireJS with the right data-main. Check out a full example of this with AngularJS in the Play Angular Seed Activator template.

Now using RequireJS is just normal syntax (no more webjars! prefix), like:

require(["jquery"], function(jquery) {
    console.log(jquery)
});

All of this was added very recently so make sure you are using at least webjars-locator version 0.12 and webjars-play version 2.2.1-2. Also this change may cause some incompatibilities in the WebJar RequireJS config files (webjars-requirejs.js) so if you experience strange behavior please file an issue on the WebJar.

Let me know how it goes!

Posted in JavaScript, WebJars | 7 Responses

Presenting Play Framework and Reactive This Week in Boulder, Dallas, and Vancouver

This week I’ll be circling around North America presenting about Play Framework and Reactive Apps. Here is the lineup:

  • Tuesday Feb 11 in Boulder, Colorado at the Boulder JUG:
    6pm – Intro to Play Framework
    7:30pm – Building Reactive Apps
  • Wednesday Feb 12 in Dallas, Texas at the Java MUG:
    6:30pm – Building Reactive Apps
  • Thursday Feb 13 in Vancouver, BC at the inaugural Vancouver Reactive Programmers meetup:
    7pm – Building Reactive Apps

It is going to be a fun week – I hope to see you at one of these events!

Posted in Play Framework, Reactive | 1 Response

Building Reactive Apps in Boston

Tomorrow night (Jan 15, 2014) I will be presenting Building Reactive Apps in Boston. There will be lots of live coding and only a couple slides. Hope to see you there!

Posted in Reactive | Leave a comment

NightHacking with Play Framework and Scala

At Devoxx 2013 Stephen Chin interviewed me on his NightHacking video podcast about Play Framework, Scala, and Reactive. Here is the recording with some live coding fun:

Posted in Play Framework, Reactive, Scala | Leave a comment

WebJars Took Off in 2013

A little over a year ago I launched WebJars with the goal of bringing some simplicity and sanity to how client-side JavaScript and CSS libraries are used in the JVM ecosystem. Since then WebJars has grown to 237 libraries and around 40,000 downloads per month! Check out the stats from Maven Central:

Note: It seems that some of the download stats for September are counted as October since averaging the two produces a more likely curve.

In the past year not only has the number of WebJars grown but the number of JVM web frameworks that support WebJars has also grown. There are now nine documented approaches for using WebJars in Play Framework, Servlet 3 containers, JSF, Grails, Dropwizard, Spring MVC, Apache Tapestry, Apache Wicket, and Ring (Clojure). The community has really stepped up to help support the effort by contributing documentation, new WebJars, and version bumps.

2013 was a great year for WebJars! A huge thanks to everyone who contributed. Lets hit 100k downloads a month in 2014!

Posted in WebJars | 1 Response


  • View James Ward's profile on LinkedIn