nam nam - 22 days ago 5
TypeScript Question

How to combine play framework and angular2?

My question is about how to organize the front and the back together in the project.
As far as I know, there are two ways to do such thing


  1. Group the front and the back in one project using web-jars dependencies and sbt plugins. So sbt will run all the necessary operations like
    uglify
    ,
    concat
    ,
    compilation
    (
    typescript
    to
    javascript
    )...

  2. Separate the front and the back and deploy them separately. In this case the back end must add the header
    Access-Control-Allow-Origin
    . This way the front and the back can be deployed in 2 different hosts. And the tool to be uses will be npm and gulp/grunt

  3. Mix of 1 and 2. Still use the same repository for the front and the back but the front is build and generated by external tools like npm, bower and gulp/grunt



For the moment, there is not a lot of docs for option 2 and 3. Also the
typescript
plugin is not yet ready.

Which way is better for scala play + angular2 development ?

Answer

I have been working with several Angular and Angular 2 apps recently and dealt with a similar problem. For all the scenarios, our backend and frontend apps were separate in terms of code and were communicating only via REST interfaces. Still, we deliver both - frontend and backend part and it felt natural to use one hosting server for both (could be Play Framework or Tomcat).

Option #1 At the beginning, we opted for this one. Webjars look like a miracle and several sbt or maven plugins can help you out with the minification, compilation, linting etc. of your frontend project. This might go well for some. Unfortunately, I have found this workflow unnatural. Some plugins were missing or their configuration was difficult. Webjars are not always up to date, some of them are automatically available, some not... etc. In a simple project it might work, but for me, it was not enough.

Option #2 We have tried separate servers for development but we quit fast. For most actions, you still need your both - frontend and backend server. So you have to start both. It means you have 2x more commands or workflows to remember and teach others. The CORS is not a big issue, but you might consider disabling it for production, that means extra work in the project. Developing backend or frontend separately was faster this way, but in my opinion, if you are to supply both - your development process should help you with it.

Option #3 That is the one we are using. With sbt it is possible and quite comfortable. With SbtWeb plugin you are able to set playRunHooks to whatever you like, fe:

playRunHooks += {
  Process(Seq("npm", "install"), file(portal)).lines.foreach(println)
  RunSubProcess(portal, "npm", "run", "watch")
}

RunSubProcess can be found here.

So cutting the long story short, you let Play Server to serve your static content, but ignore it's changes. And all the rest it taken care of by npm, gulp, webpack, grunt - whatever you choose. There is plenty of JavaScript build tools, plugins and templates to help you out. You do not need any strange sbt plugin, simply allow the JavaScript world to do it's job.

As a sample project you might want to check out Activator template Play Framework with Angular 2 and Webpack 2 and it's project is hosted on GitHub: play-ng2-webpack2. It helped me out a bit.

It is also now possible using Tomcat, with xsbt-web-plugin and developmentMode. The philosophy is similar.

Hope you find your way :).