5

If anyone has experience using Vue.js as a frontend for a Play Framework application, I'd like to know the recommended approach.

My current setup is a Play application (in Java) with Models, Controllers, and DAOs for handling REST requests - this is effectively my backend. Now Play also lets you use the Twirl template library to create views that can be served as static HTML. However, I found the Twirl syntax needlessly complex and difficult to compose views for a single-page-app. I'd prefer using something more fine-tuned for UI work like Vue

My research shows two options for integrating Vue to Play:

  1. Using Webjars:
    Its some sort of Play plugin that bundles JavaScript libraries like JQuery into .jar files that can be deployed by Play. Frankly, I don't understand the process and I have no idea how this would let me write my view in .vue files.

  2. Using a separate Vue project loosely connected to the Play backend:
    This is my current outlook before posting this question. I suppose I could create a standard Vue Webpack project using the vue-cli and NPM, then I can call the Play backend APIs RESTfully. The problem with this is the additional complexity of deploying a backend and a frontend separately. I'd prefer everything in one Play application (project folder)--backend and frontend.

Which one of these is the way to go? I am also open to new suggestions. For any suggestions, please explain the advantages of that approach and preferably provide a minimal working example (a Github repo will suffice).

Thanks.

eyeezzi
  • 585
  • 5
  • 18

5 Answers5

2

Here is a project that uses Play & Vue.js with WebJars: https://github.com/dreamhouseapp/dreamhouse-einstein-vision

Note that the project hasn't been updated to the latest Play.

Docs on using WebJars and Play are at: http://www.webjars.org/documentation

James Ward
  • 28,966
  • 9
  • 47
  • 79
  • Thanks for the link, however, it does not address my concern with using Webjars - how do you use components in a .vue file with this setup? The repo you provided only shows a Vue component inside an index.scala.html file (defeating the whole goal of modularity). – eyeezzi Oct 13 '17 at 17:18
  • It looks like `.vue` files require Webpack or Browserify to transform / load them. These tools only work on Node. So unless someone has created an sbt plugin for them, you won't be able to use them with Play / other sbt-based tools. – James Ward Oct 13 '17 at 20:13
  • you can create vue subproject under your root project and work like with just plain node/webpack project, proxyfying requests to backend, then write sbt task to build vue project before building whole play project to destination folder somewhere in public folder. That's in case you need SPA, but if you got only some parts of interface included with vue, there is no way to make it work like that (only webjars I suppose) – cutoffurmind Nov 22 '17 at 13:21
2

I've been trying to achieve the same thing and I've managed to find a few github repos with Play + Vue starter projects. play-vue-webpack looks like the best for my needs.

It couples Play on the backend with a webpack/webpack-dev-server setup on the front end with .vue components, hot module reloading etc. The webpack server is started by the sbt run hook so it's fairly seamless (although in my experience, stopping the server with CTRL+C only stops the backend and I've had to manually stop the node process separately).

Tim Barclay
  • 747
  • 8
  • 20
2

Choosing which way to go is tricky. It depends on what you want to achieve.

At GIVE.asia, we go the traditional route by making sbt-vuefy for hot-reloading *.vue to *.js when running sbt run.

You seems to capture the disadvantage of SPA pretty well; That is the reason we are not using SPA.

Here's some more info (e.g. sending data from backend to *.vue) on how we integrate Vue.js with our Playframework: https://give.engineering/2018/06/05/vue-js-with-playframework.html

The test project in sbt-vuefy might also give you a more complete picture.

I hope you find it helpful.

Tanin
  • 1,741
  • 1
  • 13
  • 18
  • 1
    Interesting approach with _sbt-vuefy_. It will indeed be very handy for SSR, but at the time I was working on project in concern, we totally wanted an SPA, so we went with something like the accepted answer. – eyeezzi Jul 26 '18 at 20:22
1

First we used a Webpack-SBT setup like the repo suggested by @Tim Barclay (play-vue-webpack), although with our own handcrafted Webpack config files and SBT hooks...it was pretty time consuming and required a good knowledge of Webpack internals.

So we later went with Option 2 in the original question: Using a separate Vue project loosely connected to the Play backend. Initially it was more work indeed, but as the codebase grew, it was way easier to understand and maintain than the earlier approach of coupling the 2 codebases.

eyeezzi
  • 585
  • 5
  • 18
  • On top of this, I think it's worth stressing one of the main benefits of separating things into separate microservices - isolation of interests. Keeping everything in one big repo is terrible for a number of reasons: code is hard to maintain, if something breaks the whole service falls over rather than just a small part of it, testing individual microservices is much simpler (in my experience)... imo, while it can be annoying to have multiple things running on different ports, it makes my life much simpler in the long run. – James Whiteley Feb 21 '19 at 11:42
0

There are several possible solutions to get it working:

  1. Using sbt plugins. There are multiple sbt plugins that can help to get vuejs working. As for me the disadvantage of this approach is tight coupling. If something changes in vue build (or you want to customize it) or author of sbt plugin stops supporting, it can take a lot of time to solve the issues.

  2. Keep frontend and backend separate. You can use webpack proxy (https://webpack.js.org/configuration/dev-server/) for backend. That works for any frontend library you use, doesn’t matter whether you it is vuejs, angular or react.

  3. Sometimes it needs to have something between #1 and #2 options for example to inject CSRF token to page, etc. It that case you can simply proxy frontend by Play on DEV mode and use built static assets in PROD mode. As for me that’s the most flexible solution. You can review how it works on this https://github.com/SunPj/silhouette-vuejs-app github project

kraken
  • 444
  • 6
  • 17