5

As advertised, the rjs in Play can

ensure that any JavaScript resources referenced from within a WebJar are automatically referenced from the jsdelivr CDN. In addition if any .min.js file is found then that will be used in place of .js. An added bonus here is that there is no change required to your html!

However, I cannot seem to get any of that to work.

  1. I tried running my Play app in production mode, and all my webjar javascripts are still being referenced as local.
  2. I do not see the .min version of javascript files being used in production.
  3. I cannot get dependency injection to work in production mode. For example, when I want to inject jquery in my code like this

    define(['jquery'], function ($) { 'use strict'; console.log($.grep); return { sum: function (a, b) { return a + b; } }; });

I can get this to work fine in dev mode, but in production mode, the rjs failed saying

[info] Error: ENOENT, no such file or directory '/Users/khanguyen/Desktop/rjsdemo/target/web/rjs/build/js/jquery.js'
[info] In module tree:
[info]     main
[info]       app
[info] 
[info] Error: Error: ENOENT, no such file or directory '/Users/khanguyen/Desktop/rjsdemo/target/web/rjs/build/js/jquery.js'
[info] In module tree:
[info]     main
[info]       app
[info] 
[info]     at Error (native)

Obviously it is looking at the wrong location for jQuery, despite the config setup generated by Webjar

requirejs.config({"paths":{"jquery":["/webjars/jquery/1.11.1/jquery","jquery"]},"shim":{"jquery":{"exports":"$"}},"packages":[]})    }

to have the correct location for jquery.

I am using Play 2.4.0, with pipelineStages := Seq(rjs, digest) setup in my build.sbt.

Please let me know where I got it wrong.

Thanks!

Khanetor
  • 9,495
  • 8
  • 31
  • 67
  • 1
    I'm having the same problem, I wonder if it's a configuration problem and have thus opened an issue here https://github.com/webjars/sample-play2/issues/7 – Mirko Stocker Jun 05 '15 at 20:02
  • Here is what I noticed so far, without clear explanation for why things work or do not work. You must use Classic Webjars. When you declare your `paths` in main.js, wrap the urls in [square brackets]. I decided to ditch the Webjar module because I don't want 2 versions of the same file. Let me know how it goes. I will write post with instruction once I figure out how to put this together. – Khanetor Jun 06 '15 at 00:56
  • You ditched the webjar module? So you're not using them anymore? That would be unfortunate. I still wonder if we're simply missing some configuration or maybe there's an incompatibility (sbt-rjs hasn't been updated in a while). – Mirko Stocker Jun 06 '15 at 13:06
  • Just to clarify, I use Webjars, but I do not use the webjar-play module. – Khanetor Jun 06 '15 at 13:09

1 Answers1

4

It turns out that RequireJS optimization support does not apply to all Webjars, but rather limited to Classic Webjars. enter image description here

Even then, a webjar build file has to be included with the regular module in order for rjs to work. enter image description here

If you look at the jQuery classic webjar, for example, you will see that a special webjar build instruction is included. Take a look at that file for your information. enter image description here

Once you have identify a webjar that is RequireJS ready, you can let sbt-rjs does it thing. Here is my setup for reference:

/** javascripts/main.js **/
'use strict';

requirejs.config({
    paths:{
        'jquery': ['../lib/jquery/jquery'],
        'react': ['../lib/react/react'],
        'bootstrap': ['../lib/bootstrap/js/bootstrap'],
        'react-bootstrap': ['../lib/react-bootstrap/react-bootstrap']
    },
    shim: {
        'bootstrap': {
            deps: ['jquery']
        },
        'react-bootstrap': {
            deps: ['react']
        }
    }
});

Remember to have square brackets, otherwise CDN replacement will not happen.

For the non-requirejs ready scripts, you should not have square brackets when declaring the paths. Otherwise, rjs will refuse to build with error path fallback not supported. Of course, you won't get the CDN benefit. Just a side note, RequireJS css optimization works, too. But only limited to inlining the css, like the regular Requirejs does.

Khanetor
  • 9,495
  • 8
  • 31
  • 67
  • Thanks! I expected that the `requirejs.config` would be generated, but that doesn't seem to be the case. – Mirko Stocker Jun 06 '15 at 15:50
  • Correction, you don't need the square brackets for cdn replacement to kick in. – Khanetor Jun 12 '15 at 05:13
  • A few things to point out... `sbt-rjs` does not use the WebJar RequireJS configs. So you have to manually create your configs when using `sbt-rjs`. The built-in WebJar RequireJS config used to come from `webjars-requirejs.js` but now comes from the `pom.xml` and is exposed via `webjars-locator` for client-side RequireJS module loading. The NPM and Bower WebJars should work just like the Classic WebJars for `sbt-rjs` since they get extracted in the same way. – James Ward Jun 12 '15 at 13:35