BrowserSync proxy in top of a Play Framework server
TL;DR ‘coz I’m a h4k3r
Full source code of the demo is on GitHub with a nice and simple README on how to bootstrap the project.
What are you talking about dude?
Play Framework is an HTTP server written in Scala. It is super cool and you should probably give it a try. Let’s say you are using it, you really enjoy how productive it is, only having to refresh your browser to see all your code modifications, but you want to go further, you want live-reloading! There are several tools doing that.
Introducing BrowserSync. It provides 2 killers features. One is live-reloading: it can monitor resources, and when it detects some modifications, it will reload the browser page to load them. Even better, if possible, it will hot deploy them, meaning they will be loaded without reloading the page. That’s the case for CSS files which are loaded and the page repainted to display the new design without any refresh. The second one is to keep synchronized several browsers across devices. And we are not talking about resources only but about all user actions. If you scroll on one browser, it will scroll on all connected browsers, same for clicking on a button, and so on…
Let me say it again with a concrete example. You are on your computer, one screen with your source code, another one with Chrome opened and a last one with Firefox. You also have an iPad tablet and an Android smartphone connected to your computer. All of those have your application main page opened. Each time your edit your code, they will all reload and display the new result (hot deploy in case of CSS). When you are ready to test interactions, you just go to, let’s say, your Chrome browser and start scrolling and clicking. All your screens will start moving and doing the actions everywhere. Talk about increasing productivity!!
What about assets that require compilation? Such as SCSS, LESS, Stylus, CoffeeScript, etc… No biggy bro (or sis), we have you covered. In this demo, we will use Gulp to monitor those resources, compile them, and pass them to BrowserSync for live-reloading (obviously not losing the hot deploy if possible). You can freely use whatever build tool you want, be it Grunt, Broccoli, …
BrowserSync could be used as the web server, that’s the easiest way to use it, and I’m actually doing it when my Play server is only here to provide a REST API. Consider doing that when you don’t need Scala templates or when you cannot use them (for example if you want to embed all your standalone HTML files inside a Cordova / PhoneGap application).
9000 for Play, in this demo, we will set the proxy on port
9001 (it would have been around
3000 by default, but I didn’t want anyone to freak out so I put it as close as possible to Play default one).
We also want to live-reload some of our resources. I kept it simple for this demo, but you are free to add as many as your want. We will use the
files property of BrowserSync configuration and set and array of files to monitor (it supports wildcards). Here, we are monitoring all CSS files from
app/views. There are two important points to notice here. First, we are referencing files based on their path on the source code, not on their actual url. For example,
public/stylesheets/main.css will be served by Play as
assets/stylesheets/main.css, but BrowserSync only needs to know the real path, after that, you can map it to whatever url you want. Second, we are monitoring Scala templates, and it’s fine because when BrowserSync will detect a modification, it will reload the page, and Play will re-compile the template before serving it, so it will display the new version. It works just fine with both
~run , the latest being faster.
Here is a super small configuration for BrowserSync to enable such a proxy. You can read the online documentation to extend it.
What about compiled assets?
It’s so easy that it’s nearly frustrating. In the demo, the
main.css file is generated from
main.less. I have two Gulp task to handle that: one for compilation and one to monitor any modification.
Wait, where are sbt-web and webjars?
Yeaaaaah… so lately, Play has introduced all those stuff on managing assets using SBT, some plugins and webjars. It works just fine but for me, it’s just as strange as if I would install Play from NPM. It’s cool if people want to try to merge two super different worlds (front-end and back-end), be it Node.js or scala.js, but I’m totally not ready for that. As a full stack developer, I want to enjoy each world with its own ecosystem, not trying to bend one into the other.
package.json so it’s not blocking at all. It tooks me less than an hour. I would be curious on how to do that using webjars? Anyway, sorry for not planning any proof of concept using webjars if that’s what you are using.
And that’s it! As I said at the beginning of the article, the demo is on GitHub, feel free to clone and play with it. Enjoy and thanks for reading.