typesafehub / angular-seed-play

initial
Other
118 stars 43 forks source link

Demonstrate automatically wiring up the webjars-requirejs.js of the dependencies files with play 2.3 #21

Closed hsyed closed 10 years ago

hsyed commented 10 years ago

I just retrofitted an older version of the seed project (2.2) to 2.3 and want to get the dependencies to wire up their webjars-requirejs.js files automatically. The recent seed project does not demonstrate this, and it doesn't have a dependency on webjars-play anymore so I cannot figure out what I am doing wrong.

Specifically I do not want to do this as it defeats the purpose of webjars and sbt integration :

requirejs.config({
    paths: {
        'angular': ['../lib/angularjs/angular'],
        'angular-ui-router' : ['../lib/angular-ui-router/angular-ui-router'],
        'angular-resource' : ['../lib/angularjs/angular-resource'],
        'ui-bootstrap-tpls' : ['../lib/angular-ui-bootstrap/ui-bootstrap-tpls']
    },
    shim: {
        'angular': {
            exports: 'angular'
        },
        'angular-ui-router' : {
            deps : ['angular']
        },
        'angular-resource' : {
            deps : ['angular']
        },
        'ui-bootstrap-tpls' : {
            deps :['angular']
        }
    }
});

My config :

routes :

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# Enable webjar based resources to be returned
GET        /contentselectors                 controllers.Assets.at(path="/public",file="/json/ContentSelectors.json")

# Home page
GET        /                                 controllers.Application.index()

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

# Map the JS resource paths
GET        /*file                            controllers.Assets.versioned(path="/public", file: Asset)

build.sbt :

name := "angular-seed-play"

version := "1.0-SNAPSHOT"

scalaVersion := "2.10.4"

resolvers += "ReactiveCouchbase repository" at "https://raw.github.com/ReactiveCouchbase/repository/master/snapshots"

libraryDependencies ++= Seq(
  "org.webjars" %% "webjars-play" % "2.3-M1",
  "org.webjars" % "requirejs" % "2.1.11-1",
  "org.webjars" % "angularjs" % "1.2.13",
  "org.webjars" % "bootstrap" % "3.1.1-1",
  "org.webjars" % "angular-ui-router" % "0.2.10-1",
  "org.webjars" % "angular-ui-bootstrap" % "0.11.0-2",
  "org.reactivecouchbase" %% "reactivecouchbase-play" % "0.3-SNAPSHOT"
)

lazy val root = (project in file(".")).enablePlugins(PlayScala)

pipelineStages := Seq(rjs, digest, gzip)

plugins :

// Comment to get more information during initialization
logLevel := Level.Warn

// The Typesafe repository
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"

// Use the Play sbt plugin for Play projects
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-rjs" % "1.0.1")

addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-gzip" % "1.0.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0")

template :

<head>
  <meta charset="utf-8">
  @*<meta name="viewport" content="width=device-width, initial-scale=1">*@
  <title>My AngularJS App</title>
  <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet" href="@routes.Assets.versioned("css/app.css")">
  <script data-main="@routes.Assets.versioned("js/main.js")" src="@routes.Assets.versioned("lib/requirejs/require.js")"></script>
  @*<link rel="stylesheet" href="@routes.Assets.at("css/app.css")">*@
    @Html(org.webjars.play.RequireJS.setup("index"))
</head>

error :

play.api.Application$$anon$1: Execution exception[[NoSuchMethodException: controllers.ReverseAssets.at(java.lang.String)]]
    at play.api.Application$class.handleError(Application.scala:296) ~[play_2.10-2.3.0.jar:2.3.0]
    at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.10-2.3.0.jar:2.3.0]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:205) [play_2.10-2.3.0.jar:2.3.0]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:202) [play_2.10-2.3.0.jar:2.3.0]
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33) [scala-library.jar:na]
Caused by: java.lang.NoSuchMethodException: controllers.ReverseAssets.at(java.lang.String)
    at com.zeroturnaround.javarebel.uz.getMethod(JRebel:713) ~[na:201311271505]
    at java.lang.Class.getMethod(Class.java) ~[na:1.7.0_45]
    at org.webjars.play.RequireJS$.nastyReflectedRoute$1(RequireJS.scala:13) ~[webjars-play_2.10-2.3-M1.jar:2.3-M1]
    at org.webjars.play.RequireJS$.nastyReflectedAssetsRoute$1(RequireJS.scala:18) ~[webjars-play_2.10-2.3-M1.jar:2.3-M1]
    at org.webjars.play.RequireJS$.setup(RequireJS.scala:22) ~[webjars-play_2.10-2.3-M1.jar:2.3-M1]
huntc commented 10 years ago

Sbt-web's approach is quite different. Rjs is now configured exactly as if you were using it outside of Play.

The purpose of WebJars is to leverage existing tooling and infrastructure.

My guess here is that an older version of play is included given the dependency on WebJars-play.

I'm going to close this issue for now.

hsyed commented 10 years ago

Yes I thought that might be the case (new way of doing this), in this case could you give me some pointers as to how best achieve my use-case with sbt-web (loading the webjars-requirejs.js automatically based on the web jars dependencies declare in the build file) ?

We are considering moving to web jars at work and would need the use-case above. We are loading dozens of dependencies at the moment manually, and this is without any other tools --i.e., no NPM or requires etc, just the angular module loader / injector. I need to nail this down so we can begin porting our in house JS modules to web jars, but it wouldn't be worth the investment for the next project unless I can remove the boilerplate above.

Sorry, I'm really new to web-development and play in general. Learning the whole stack --i.e., angular, css, requires, JS, play, web unit testing etc simultaneously :(.

We are in the process of a typesafe subscription for our team :D Guess I could raise a ticket once it goes through.

huntc commented 10 years ago

You'll need to declare an rjs path config in your main.js - as per the project provided. The upside of this is that sbt-rjs looks for them and automatically substitutes CDN paths for the WebJars when you create a dist for production.

hsyed commented 10 years ago

So is this the currently prescribed solution ?

requirejs.config({
    paths: {
        'angular': ['../lib/angularjs/angular'],
        'angular-ui-router' : ['../lib/angular-ui-router/angular-ui-router'],
        'angular-resource' : ['../lib/angularjs/angular-resource'],
        'ui-bootstrap-tpls' : ['../lib/angular-ui-bootstrap/ui-bootstrap-tpls']
    },
    shim: {
        'angular': {
            exports: 'angular'
        },
        'angular-ui-router' : {
            deps : ['angular']
        },
        'angular-resource' : {
            deps : ['angular']
        },
        'ui-bootstrap-tpls' : {
            deps :['angular']
        }
    }
});

require(['angular', './controllers', './directives', './filters', './services',
        'angular-ui-router', 'angular-resource','ui-bootstrap-tpls'],
  function(angular, controllers) {
...
}

This would become rather unwieldy when dozens of dependencies are involved.

huntc commented 10 years ago

I agree with you. However do you accept that this is an rjs issue and not really a WebJars one?

That said, we could probably re-instate some support for rjs in sbt-web if this becomes a common issue.