Search code examples
scalaplayframeworkrequirejsreactjswebjars

PlayFramework with Scala, WebJars, ReactJS and RequireJS?


I am looking for an example about combining the four technologies in the title :) I have a working ReactJS application using Play, Scala and WebJars, it's here on GitHub.

Now I would like to add RequireJS, but I'm not sure how to go, especially because it seems to require a different JSXTransformer? If anybody has a pointer (or even a PR) it would be very appreciated.


Solution

  • This is not the easiest thing to do, but I was able to pull it off. I will give you some tips here. I also uploaded my own project to github. This is a very simple snake game built using React and RequireJs. It based on Webjars and Play Framework.

    Remember that RequireJs is part of Play Framework. Here's a step by step guide to create React/RequireJs/WebJars/Play integration:

    1. In your plugins.sbt add addSbtPlugin("com.github.ddispaltro" % "sbt-reactjs" % "0.5.2"). This is a plugin which transforms JSXes into JSes and also strips flow types if you want that.
    2. In your main scala.html file add @helper.requireJs(core = routes.WebJarAssets.at(WebJarAssets.locate("require.js")).url, module = routes.Assets.at("javascripts/main").url). This will add add a script tag with data-main and src attributes that are used to bootstrap your RequireJs app.
    3. Create react.js file in your assets/javascripts folder:

      define(['../lib/react/react-with-addons'], function(React) {
          window.React = React;
          return React;
      });
      
    4. Create main.jsx file in your assets/javascripts folder:

      require.config({
         // standard requirejs config here
      });
      
      require(['react', 'components/YourComponent'], function(React, YourComponent) {
          'use strict';
          $(document).ready(function() {
              React.render(<YourComponent />, document.getElementById('container'));
          });
      });
      
    5. Your standard React component goes to assets/javascripts/components/YourComponent.jsx and is defined like standard RequireJs module. Remember to return a React class:

      define(function(require) {
          var React = require('react');
          var AnotherComponent = require('components/AnotherComponent');
          return React.createClass({ ... });
      }
      

    I hope that helps. If you have any questions, please let me know.