I am trying to use the sbt-web plugin without the play framework and instead build a webapp using the xsbt-web-plugin.
I have gotten the sbt-web plugin working correctly in handling the asset pipeline and have it creating a valid webjar output (via packageBin) as well as the standard "web/public/main" output (via assets).
Separately, I have been using the xsbt-web-plugin to develop a webapp and serve that webapp from within SBT (via container:start). The webapp project can consume webjar dependencies from mavenCentral and refer to those resources without issue.
What I have not been able to figure out is how can I get the xsbt-web-plugin to include assets coming out of the sbt-web pipeline in the web application. It seems that the best I can do is to get them into the CLASSPATH. (From what I understand, this is all that play needs, because they have an "Asset Controller" that serves those assets out of the CLASSPATH and therefore doesn't need them to be available as static assets to the web application).
I have made a public GitHub repository (https://github.com/MartinSnyder/serving-sbt-web-output) that demonstrates what I am trying to do.
My plugins.sbt is:
resolvers += Resolver.typesafeRepo("releases")
addSbtPlugin("com.typesafe.sbt" % "sbt-web" % "1.1.1")
addSbtPlugin("com.typesafe.sbt" % "sbt-less" % "1.0.6")
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "1.0.0")
My build.sbt is:
name := "Example project serving sbt-web output from within SBT"
organization in ThisBuild := "com.martinsnyder"
version in ThisBuild := "0.0.1"
scalaVersion in ThisBuild := "2.11.6"
lazy val example_webjar =
project
.in(file("example_webjar"))
.settings(libraryDependencies ++= Seq("org.webjars" % "requirejs" % "2.1.16"))
.enablePlugins(SbtWeb)
lazy val example_webapp =
project
.in(file("example_webapp"))
.dependsOn(example_webjar)
.settings(libraryDependencies ++= Seq(
"javax.servlet" % "servlet-api" % "2.5" % "provided",
"org.eclipse.jetty" % "jetty-webapp" % "9.3.0.M2" % "container",
"org.eclipse.jetty" % "jetty-plus" % "9.3.0.M2" % "container",
"commons-logging" % "commons-logging" % "1.2" % "container"
))
.enablePlugins(SbtWeb)
.settings(jetty(): _*)
The HTML file in the webapp is:
<html>
<head>
<title>Example</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<link rel="stylesheet" type="text/css" href="lib/example_webjar/css/main.css">
<link rel="stylesheet" type="text/css" href="webjar/example_webjar/0.0.1/css/main.css">
<script src="webjars/requirejs/2.1.16/require.js"></script>
</head>
<body>
<div class="red">Red</div>
<div class="green">Green</div>
</body>
</html>
As things currently stand, requirejs is served successfully, as it is coming from a pre-build webjar. The three tags are all different and failing attempts to reference the asset output from sbt-web.
The best-case scenario I am trying to achieve is to get the sbt-web plugin output(target/web/public/main/) included in the xsbt-web-plugin webapp output (target/webapp/). I would settle for the xsbt-web-plugin being able to access the project dependency as a webjar.
If you tell xsbt-web-plugin to use sbt-web's output as its Web application resources directory, it should get you most of the way.
Just add webappSrc in webapp <<= WebKeys.assets in Assets
as a setting to your example_webapp
project:
lazy val example_webapp =
project
.in(file("example_webapp"))
.dependsOn(example_webjar)
.settings(libraryDependencies ++= Seq(
"javax.servlet" % "servlet-api" % "2.5" % "provided",
"org.eclipse.jetty" % "jetty-webapp" % "9.3.0.M2" % "container",
"org.eclipse.jetty" % "jetty-plus" % "9.3.0.M2" % "container",
"commons-logging" % "commons-logging" % "1.2" % "container"
))
.enablePlugins(SbtWeb)
.settings(jetty(): _*)
.settings(webappSrc in webapp <<= WebKeys.assets in Assets)