Instructions for Play 2.1 (example app)
WebJars can be added as dependencies to an app by simply adding them to the
project/Build.scala file. There is also a helper library named
webjars-play that makes it easy to reference WebJar assets. Here is an example
project/Build.scala file with
webjars-play and the
bootstrap WebJar as dependencies:
import sbt._
import Keys._
import play.Project
object ApplicationBuild extends Build {
val appName = "foo"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
"org.webjars" % "webjars-play" % "2.1.0-1",
"org.webjars" % "bootstrap" % "2.1.1"
)
val main = Project(appName, appVersion, appDependencies).settings()
}
After changing a Play 2's dependencies you will need to restart Play.
The
webjars-play helper library has a wrapper around the Play Static Asset Controller that can locate and serve WebJar assets. A new route to
WebJarAssets needs to be added to the
conf/routes file:
GET /webjars/*file controllers.WebJarAssets.at(file)
To use Play 2's reverse routing to resolve the URL to an asset you can do the following in a template:
<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>
Requirejs is a popular implementation of the
AMD
specification - a means by which JavaScript applications can be modularised. The easiest way of thinking
about AMD is that it is JavaScript's equivalent of package and import statements (or namespace and
include statements depending on your preferences!). These instructions assume basic knowledge of
requirejs.
In summary requirejs is supported in the form of a new
loader plugin named "webjars". For example a
dependency on jquery file is specified from within JavaScript as follows:
define(["webjars!jquery.js"], ...
A note on using minified files: it is often best to depend on the non-minified file given
the ease of debugging things within a browser. Minification should be performed as a step prior
to the deployment of code.
Bootstrapping requirejs
Requirejs is often loaded like this:
<script data-main="scripts/main.js" type='text/javascript' src='scripts/require.js"))'></script>
Given Play directory conventions and Webjars we can do this:
<script data-main="javascripts/main.js" type='text/javascript' src='@routes.WebJarAssets.requirejs'></script>
The above statement will load a script that will configure requirejs with
application routes so that routing can be resolved using a webjars loader plugin. Requirejs is then resolved by
that same script using those routes and then loaded dynamically.
The rationale for this is so that the version of requirejs can also be specified
as a webjar dependency in the Play application's build file:
val appDependencies = Seq(
"org.webjars" % "webjars-play" % "2.1.0-1",
"org.webjars" % "requirejs" % "2.1.1"
)
Using requirejs
Usage is as normal. The following code block illustrates how jquery.js is located:
define(["webjars!jquery.js"], function() {
// $ can be accessed within here as jquery.js declares it as a global.
});
Advanced usage
Requirejs can be configured further when a webjar is created.
For example the bootstrap library requires jquery to be
loaded in order to execute. This can be achieved with the following
requirejs configuration in a file named
webjars-requirejs.js. webjars-requirejs.js must reside in the META-INF/resources/webjars/{artifactId}/{version} folder.
Here is what it would look like:
requirejs.config({
shim: {
bootstrap: [ 'webjars!jquery.js' ]
}
});
When a webjar module is requested the webjars-requirejs.js is evaluated. In the above case any existing
requirejs configuration is extended. When webjars!bootstrap.js is requested "bootstrap" property is looked up
(the webjars! prefix and .js suffix are removed to form a module name that
requirejs is happy with). Any dependencies are then obtained and loaded prior to the requested module.
The webjars project has already provided a number of webjars configured in this way
(including the bootstrap library).
Instructions for Servlet 3
With any Servlet 3 compatible container, the WebJars that are in the
WEB-INF/lib directory are automatically made available as static resources. This works because anything in a
META-INF/resources directory in a JAR in
WEB-INF/lib is automatically exposed as a static resource.
First add a WebJar as a dependency of your application in the
pom.xml file, like:
<dependencies>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
Then simply reference the resource like:
<link rel='stylesheet' href='webjars/bootstrap/2.1.1/css/bootstrap.min.css'>
Instructions for Grails (example app)
Grails manages static resources (such as javascript and css files) with the resources plugin. The resources plugin manages static resources via modules, like the Jquery Module, that define via a config file which static resources a module requires. For a more details explanation see the
Grails docs on using Static Resource.
The
Grails Modules Manager plugin allows dependencies on web libraries to be declared in the Grails build configuration file,
BuildConfig.groovy. It resolves theses dependencies and creates modules that can be used by the resources plugin. It does this by downloading the jar files from webjars.org and extracting the web libraries from the jar files. It then creates grails specific resource modules from these web libraries.
Steps for using the plugin:
- Clone the modules manager plugin from
https://github.com/groovydev/modules-manager-grails-plugin.git
- Build the plugin:
grails package-plugin
- Install the plugin into your grails project from the file system - this assumes the plugin is in
the same parent directory as the project:
grails install-plugin ../modules-manager-grails-plugin/grails-modules-manager-0.2.1.zip
- Define the javascript and css dependencies. In grails-app/config/BuildConfig.groovy
add:
dependencies {
compile 'org.webjars:bootstrap:2.1.1'
}
- Run the refresh modules command which will download the necessary javascript and css dependencies:
grails refresh-modules
- Notice how the plugin added the file conf/ModulesBootstrapResources.groovy. This module config file is used by the resources plugin to define the module dependencies and static resources.
- Add the module dependencies to the web page (see the example in views/index.gsp). This is done by adding the require tag to the html page to include the static resource modules. Also note that it is necessary to add the layoutResources tag twice to the page.
In the head tag add:
<head>
<r:require modules="jquery, bootstrap"/>
<r:layoutResources/>
And then at the bottom of the page right before the body add:
<r:layoutResources/>
</body>
- The resource manager then optimizes when the javascript is load by when it is need in the page and by default includes the javascript at the bottom of the page. For this reason it is necessary to put the javascript in a <r:script> tag so that the necessary dependencies will be included when the layoutResources tag is called. For example to use a jquery initialization function add the following to the page:
<r:script>
$(function (){ ... }
Instructions for Dropwizard (example app)
With Dropwizard you can easily expose WebJars through the
AssetsBundle. In your startup service's constructor setup the
AssetsBundle to map static asset requests in a
/META-INF/resources/webjars directory in JARs on the CLASSPATH to the
/webjars URL, for example:
package org.webjars;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.bundles.AssetsBundle;
import com.yammer.dropwizard.config.Configuration;
import com.yammer.dropwizard.config.Environment;
public class MainService extends Service {
public static void main(String[] args) throws Exception {
new MainService().run(args);
}
private MainService() {
super("sample-dropwizard");
addBundle(new AssetsBundle("/META-INF/resources/webjars", 0, "/webjars"));
}
}
Now you can reference a WebJar asset like:
<link rel='stylesheet' href='/webjars/bootstrap/2.1.1/css/bootstrap.min.css'>
Instructions for Spring MVC
Spring MVC makes it easy to expose static assets in JAR files using
ResourceHandlers.
First add a WebJar as a dependency of your application in the
pom.xml file, like:
<dependencies>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
Then configure Spring to map requests for
/webjars to the
/META-INF/resources/webjars directory of all the JARs in the CLASSPATH. This can be done either via XML config:
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
Note In a Servlet 3 container this can be simplified to:
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
Or Java config:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Note In a Servlet 3 container the
registry.addResourceHandler line can be simplified to:
registry.addResourceHandler("/webjars/**").addResourceLocations("/webjars/");
The reference a WebJar asset like:
<link rel='stylesheet' href='/webjars/bootstrap/2.1.1/css/bootstrap.min.css'>
Instructions for Apache Tapestry
Apache Tapestry makes it easy to expose static assets in JAR files using
contributeClasspathAssetAliasManager.
First add a WebJar as a dependency of your application in the
pom.xml file, like:
<dependencies>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
Then configure the
contributeClasspathAssetAliasManager in your
AppModule to look for assets in
META-INF/resources/webjars directories:
public class AppModule {
public static void contributeClasspathAssetAliasManager(MappedConfiguration configuration) {
configuration.add("webjars", "META-INF/resources/webjars");
}
}
Then simply reference WebJars assets in your Tapestry templates like:
<link rel='stylesheet' media='screen'
href='${asset:classpath:/META-INF/resources/webjars/bootstrap/2.1.1/css/bootstrap.min.css}'></link>
<script type='text/javascript'
src='${asset:classpath:/META-INF/resources/webjars/jquery/1.8.2/jquery.min.js}'></script>
Instructions for Apache Wicket
The Wicket integration of Webjars uses a special
IResourceFinder implementation to map
Webjars resources.
First you have to add wicket-webjars as dependency to your application in the
pom.xml file, like:
<dependencies>
<dependency>
<groupId>de.agilecoders.wicket.webjars</groupId>
<artifactId>wicket-webjars</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
And a WebJar dependency like:
<dependencies>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
Then configure your wicket application to map requests for
/webjars and instances of
IWebjarsResourceReference to the
/META-INF/resources/webjars
directory of all the JARs in the CLASSPATH. This can be done in
Application.init:
/**
* @see org.apache.wicket.Application#init()
*/
@Override
public void init() {
super.init();
WicketWebjars.install(this);
}
Then simply reference the resource like:
<link rel='stylesheet' href='/webjars/jquery/1.8.3/jquery.js'>
Or add a
Webjars*ResourceReference to your component:
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(JavaScriptHeaderItem.forReference(
new WebjarsJavaScriptResourceReference("jquery/1.8.3/jquery.js")));
}
To always use the most recent version of a WebJar asset, simply replace the version in path with
the
"current" string. When a resource name is resolved this string will be replaced with the most recent available version in classpath:
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
// current will be replaced with "1.8.3"
response.render(JavaScriptHeaderItem.forReference(
new WebjarsJavaScriptResourceReference("jquery/current/jquery.js")));
}
Instructions for Ring (example app)
Ring makes it easy to expose WebJars through the
wrap-resource function.
First add a Webjar as dependency to your application in the
project.clj file, like:
:dependencies [[org.webjars/bootstrap "2.1.1"]]
Then change your wrapper sequence to setup
wrap-resource to look for assets in
/META-INF/resources directories in JARs on the CLASSPATH:
(def app
(-> handler
(wrap-resource "/META-INF/resources")))
(defn -main []
(run-jetty app {:port (Integer/parseInt (or (System/getenv "PORT") "8080"))}))
Now you can reference a WebJar asset like:
<link rel='stylesheet' href='/webjars/bootstrap/2.1.1/css/bootstrap.min.css'>
Using clj-webjars
Alternatively you can use
clj-webjars to simplify assets integration.
By relying on
wrap-webjars ring middleware you can reference a WebJar asset like:
<link rel='stylesheet' href='assets/css/bootstrap.min.css'>
The right asset will be transparently accessed and served with proper HTTP caching behavior.