Question

After upgrade to play 2.2, I cannot make requirejs work as before.

It seems to me that the requirejs is not initialized or configured correctly. I tried to follow https://github.com/mariussoutier/play-angular-require-seed, but I cannot even make the simplest case to work.

jquery can be located correctly in main.js, but require(['jquery'].....) does not work in tag.

If someone could help me with this, it would be appreciated a lot.

webjars definition

libraryDependencies ++= Seq(
  javaJdbc,
  javaEbean,
  cache,
  "org.webjars" % "jquery" % "1.10.2",
  "org.webjars" % "requirejs" % "2.1.1",
  "org.webjars" % "webjars-play_2.10" % "2.2.0"
)     

resolvers += "typesafe" at "http://repo.typesafe.com/typesafe/repo"

requireJs += "main.js"

requireJsShim += "main.js"

main.js

 (function(requirejs) {
      "use strict";

      // -- PROD RequireJS config --
      requirejs.config({
        shim: {
          "jquery": { exports: "$" }
        },
        paths: {
          "jquery": ["/webjars/jquery/1.10.2/jquery.min"]
        }
      });
      // It works fine here        
      require(["jquery"], function($) {
        console.log($);
      });
    })(requirejs);

index.scala.html

@(title: String)

<html>
    <body>
    <script src='/lib/require.js' type='text/javascript' data-main="/assets/javascripts/main"></script>
    <script type="text/javascript">
        require(["jquery"], function($) {
            console.log($);
            });
    </script>
    </body>
</html>

main.js is loaded, and the error message in the console is

Uncaught TypeError: Property 'require' of object [object Object] is not a function 

Edit The key here is to understand the AMD concept. Although two snippets in tag are placed one after the other, they are not guaranteed execute in order. Therefore, when the second snippet runs, the requirejs may not be configured yet.

<script src='webjars/requirejs/2.1.8/require.js' type='text/javascript' data-main="javascripts/main"></script>
<script type='text/javascript'>
    // Second snippet
    require(['jquery'], function($) {return $;});
</script>

To fix this, we have two different approaches:

  1. Include the javascript code of the second snippet in main.js (specified in data-main) and Use require(['dependencies'], function() {// do second.js})
  2. Do not specify data-main field when including requirejs, and do all the configuration in the second part.

IMHO, the first approach is preferred and is the exact one used in the sample project https://github.com/mariussoutier/play-angular-require-seed

Was it helpful?

Solution

Qualifying my reply, definitely not an expert...

In your index.scala.html page, you're trying to use a script that's loaded asynchronously. That will give you random results, because it might very well not be loaded in time.

From the RequireJS site:

Note: the script tag require.js generates for your data-main module includes the async attribute. This means that you cannot assume that the load and execution of your data-main script will finish prior to other scripts referenced later in the same page.

For example, this arrangement will fail randomly when the require.config path for the 'foo' module has not been set prior to it being require()'d later:

<script data-main="scripts/main" src="scripts/require.js"></script>
<script src="scripts/other.js"></script>

// contents of main.js:
require.config({
    paths: {
        foo: 'libs/foo-1.1.3'
    }
});

// contents of other.js:

// This code might be called before the require.config() in main.js
// has executed. When that happens, require.js will attempt to
// load 'scripts/foo.js' instead of 'scripts/libs/foo-1.1.3.js'
require( ['foo'], function( foo ) {

});

Also of note... in the example you linked to, this problem is avoided, because all the usage of "require" happens in main*.js

So what I believe you need to do, is to wrap JavaScript code contained within your second script in an event handler which is listening for an event such as window.onload or DOMContentLoaded event, to delay the execution until those events have fired (and all will be present and correct).

References:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top