Hot reload, docs, where to start

65 views
Skip to first unread message

Miguel Ping

unread,
Oct 5, 2017, 10:14:57 AM10/5/17
to Lift
Hi guys,

I'm currently experimenting with some web frameworks for some pet projects of mine, and I have some questions about lift:

- I know you can make lift stateless, but what parts do need to be stateful and why?
- Is there any hot-reload facility? What's the current workflow for the senior devs? Coming from a clojure project, I don't want to restart my server every time I change a file. Don't want to buy jrebel either.
- Docs are scattered between different sites, regarding different versions of Lift. Where does one start? Lift seems to hava a big surface api, and since v3 is out I'd like some docs on v3


these questions probably crop up from time to time, but I guess that's another reason to have good quality docs.
Thanks!

Matt Farmer

unread,
Oct 5, 2017, 10:55:13 AM10/5/17
to Lift
Hey there, thanks for writing in. I'll share some of my thoughts on each of these but I'm sure others will chime in as well. :)

- I know you can make lift stateless, but what parts do need to be stateful and why?

If you accept statefulness you get a good number of security and convenience things that come along with that. For example, when you bind forms on a page statefully, all of their names are randomized for each page load making a successful CSRF attack highly unlikely. You can also minimize the amount of JS you have to write to get the same effect using, for example, CometActors. You can see those in use in this comet I wrote for a dynamic schedule editor for judicial competitions. There's very little JS that I'm actually using to get the dynamic behavior.

- Is there any hot-reload facility? What's the current workflow for the senior devs? Coming from a clojure project, I don't want to restart my server every time I change a file. Don't want to buy jrebel either.

There is no hot-reload as of yet, but you can automate the restarting of the server by prefixing the start command with a ~. This combined with a little bit of code to reconstruct a session from a cookie in my browser has been enough for me to not feel like it's very painful. But that's just me.

My experience has been that hot reloading is brittle. I've used jrebel with Lift briefly and have done some Play projects that use their hot reload capabilities. I always end up turning it off. It just doesn't seem to work so well in Scala yet, but my most recent experience with this is December, so maybe something has improved.

- Docs are scattered between different sites, regarding different versions of Lift. Where does one start? Lift seems to hava a big surface api, and since v3 is out I'd like some docs on v3

Documentation is Lift's weak point.

Lift 3 is v3 because we deleted a bunch of old, long-deprecated APIs that were no longer used outside of the Framework itself and most sites had stopped documenting a few years ago. There are some new things that were also added that may not be documented yet, but if you start with Simply Lift and the Lift Cookbook you'll learn the basics. Between that and searching the ML when you run into specific questions, you'll be able to find most of what you need with a bit of effort. The Assembla wiki is currently packed with good things, but IMO we need to consider migrating to something else soon because it's hard to maintain and navigate.

There's an ongoing effort to put some tutorial docs in the repo. There are some open PRs with this work that is ongoing. Antonio has been working on that and I'm sure he'd love some help if you're interested in contributing as you learn.

My hope is to get to a point soon where there's one place to go for Lift documentation. We're not there yet. =(

Let us know if you have any other questions!

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Miguel Ping

unread,
Oct 6, 2017, 2:38:28 PM10/6/17
to Lift
Hi,

Thanks for the reply. I'd love to contribute, but first I need to get a good understanding of how Lift works.
I like to know how a framework solves a couple of problems, so this is the questions I have right now:

- the regular dev workflow uses jetty:reload? Or the container restarts every time with every change?
- whats the "standard" way of assembling an app? Start with route, add templates, and snippets around that? 
- Do lift devs have something similar like a taglib? Eg: in angular there's something like a foreach, something like the following:

<table>
  <tr ng-repeat="item in list">
     <td>${item.xx}</td>
     <td>${item.yy}</td>
  </tr>
</table>

Don't want to discuss the merits of the approach, but it makes onboarding extremely easy, it's very easy to see what is going on.
I tried to search the Lift way of doing this but assembla is showing old code with a function that was removed ( .bind())

- Lift has an IoC container? How do you create/inject/pass things around?
- What's the scope of the javascript support? If I want to do (eg:) an autocomplete, is there js support for it, or I have to code js by hand? Again, coming from a different background, I find that JSF2 nailed the api quite nicely (without discussing the merits of JSF approach), here's an example: https://www.primefaces.org/showcase/ui/ajax/dropdown.xhtml
I would hope that lift allows such "componentization" easily, specially with javascript

Some questions may not make much sense due to differences in Lift philosophy, and for that I apologize in advance.


By the way, I checked out your app and I'm hitting an error within slick (something like this: https://github.com/slick/slick/issues/1277)

Thanks!

Matt Farmer

unread,
Oct 6, 2017, 3:40:05 PM10/6/17
to lif...@googlegroups.com
Hi there,

I'll try to answer these as best I can.

- the regular dev workflow uses jetty:reload? Or the container restarts every time with every change?

I don't understand this question. With my setup I invoke ~jetty:start and the container starts anew with each change.

- whats the "standard" way of assembling an app? Start with route, add templates, and snippets around that? 

Lift is view-first, so you generally start by building an HTML UI and specifying a SiteMap of valid URLs and iterate from there. I typically build out an entire wireframe of different pages before I start writing any functionality in Scala.

- Do lift devs have something similar like a taglib? Eg: in angular there's something like a foreach

You don't need it with CSS transforms. In Lift-land, we'd write a snippet to do this. So my HTML would be something like:

<table data-lift="MyTableSnippet.render">
  <tr class="row">
    <td class="field1">Placeholder content</td>
    <td class="field2">Placeholder content</td>
  </tr>
</table>

And then I'd have a render function in MyTableSnippet defined like:

".row" #> items.map { item =>
  ".field1 *" #> item.field1 &
  ".field2 *" #> item.field2
}

This accomplishes the same goal as the example code you mentioned above. FWIW, if you're interested in using Angular for your frontend, you may want to look at lift-ng, which provides some integration for using a Lift backend and Angular frontend.

- Lift has an IoC container? How do you create/inject/pass things around?

Lift provides automatic injection into snippets for parameterized urls, such that if you define that a URL references, say, a Campaign object in your code and the view that URL maps to calls on a snippet that takes a Campaign in its constructor, Lift will provide the Campaign for the current URL.

For other things, we provide a Factory trait with some session helpers that can work per-request or per-session.  You should also be able to bring your own injection library without much trouble, if you see fit.

- What's the scope of the javascript support? If I want to do (eg:) an autocomplete, is there js support for it, or I have to code js by hand?

In the specific example of autocomplete, as with most other things, "it depends." Lift has a fully fledged JavaScript AST that can be used to compose any kind of thing you might want to do into equivalent JavaScript. There are also modules out there that just do a good bit of the behavior for you. But neither of those may be the best fit for your project.

You should certainly go in with the expectation that you'll have to write some JavaScript. But for things the Framework provides as first-class features (e.g. Comets that can update page content) you will probably not have to write any JS for those. Autocomplete isn't really a first class feature of the framework, so I'd expect you have to fiddle with some JS there.

By the way, I checked out your app and I'm hitting an error within slick

Not sure why you're getting that as it works fine for me and on the production server, last I checked. But I haven't messed with it for a few weeks so I might be tempting fate there. heh.

Antonio Salazar Cardozo

unread,
Oct 6, 2017, 5:31:02 PM10/6/17
to Lift
There's some more regarding Lift's DI capabilities with the Factory trait Matt linked
Thanks,
Antonio
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+unsubscribe@googlegroups.com.

Miguel Ping

unread,
Oct 7, 2017, 8:06:55 AM10/7/17
to Lift
Hi all,

I remember jetty had support for reloading classes without stopping, thats what ~jetty:reload means.
It seems that the xsbt plugin doesn't support this. Maybe it isn't a showstopper, but between clojure, javascript  and ruby I'm a bit spoiled with the short turnaround.

Thanks for the great replies, I'll give it a shot and if I have questions I'll come back!

Peter Petersson

unread,
Oct 7, 2017, 10:33:47 AM10/7/17
to lif...@googlegroups.com

Hi

Just use

~jetty:start

and in most cases (as you can see in the console) jetty will reload as soon as you save your edits. There may be some glitches here and there but as long as you are not editing bootstrap.liftweb.Boot jetty will most likely pick up on your changes.

When it comes to html/css/javascript changes you might also need to press F5 from time to time.

Best regards Peter Petersson

PS This is a second try on posting a reply so if there (eventually) are two identical replies I apologize DS

Peter Petersson

unread,
Oct 8, 2017, 7:41:38 AM10/8/17
to lif...@googlegroups.com

Hi again

I noticed that using SBT 1.0.x there seems to be a degradation in whats triggering a hot reload.
I haven't read the xsbt-web-plugin (v4.0.0) documentation so maybe there is some hints in there.

best regards Peter Petersson

PS have made the same mistake again and replayed to sender instead of this list, sry for the double mails Miguel DS


On 2017-10-07 14:06, Miguel Ping wrote:

Peter Petersson

unread,
Oct 22, 2017, 4:58:00 AM10/22/17
to lif...@googlegroups.com

I just upgraded to sbt v1.0.2 (from v1.0.1) and bumped the [2] xsbt-web-plugin to v4.0.1 (from v4.0.0) and [1] **"hot reload"** of all types of resources (not just Scala) started to work (again) as it should, giving (back) a much smother Lift dev experience. 

so just using

~jetty:start

should work as expected.

[1] http://www.scala-sbt.org/1.0/docs/Triggered-Execution.html
[2] https://github.com/earldouglas/xsbt-web-plugin/blob/master/docs/4.0.x.md

best regards Peter Petersson

Miguel Ping

unread,
Oct 23, 2017, 7:02:48 AM10/23/17
to Lift
Hi Peter,

Thanks for your reply. 

Unfortunately, I couldn't make it to do hot-reload. It is in fact (re)compiling the classes in the background but jetty is shutting down and restarting, instead of picking changes.
I ran > sbt update to make sure the plugin was updated but I still see jetty shutting down and restarting on sbt console.

do you have a github repo that I can clone? Thanks!

Peter Petersson

unread,
Oct 24, 2017, 2:19:35 PM10/24/17
to lif...@googlegroups.com

Sry for taking so long to answer,

I finally got some time to check this out again and you are unfortunately right the jetty server is actually shutting down and starting up again.

best regards Peter

Cornelius Brümmer

unread,
Oct 25, 2017, 8:08:50 AM10/25/17
to lif...@googlegroups.com
As I don't see it mentioned yet:

If it's about messing around with HTML5 + CSS and Client-Side Javascript Files you can do:

> jetty:quickstart

If will arrange things so that you can just reload the page (or include those IntelliJ-stuff for webpage-auto-reload on changes).

What it will not do is to recompile any file changes in your Scala-Code.

When starting something with Lift I usually get forms and pages up and running that way without that re-deployments you get when using:

 > ~jetty:start

... which will pick up any changes (including stuff like .property files etc.)

I don't know exactly since when this stuff exists, I'm on: Scala 2.12.2 + SBT 0.13.15 + Lift 3.1.0 using Jetty for local development, as provided by SBT Plugin vom com.earldouglas (3.0.1).

Personally I think it is useful to switch between "Snippet-Implementation-Mode" (with full deployments aka. ~jetty:start) and "Moving-stuff-around-Mode" (aka jetty:quickstart).
The beauty in Lift is that there is just .html you can reorganize in the later mode and it will keep being stateful as there are no restarts etc..

I may have answered only to a tiny part of your questions, sorry for that... :-/

Best regards, Cornelius


To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code

---
You received this message because you are subscribed to the Google Groups "Lift" group.
To unsubscribe from this group and stop receiving emails from it, send an email to liftweb+unsubscribe@googlegroups.com.

Peter Petersson

unread,
Oct 25, 2017, 3:35:49 PM10/25/17
to lif...@googlegroups.com

I guess what we all like to see is something like what we have in the javascript world with for example webpack hot reload and HMR.

For that the current status (without jRebel) a jetty stop, restart sequence on resource changes gives us a lot more to wish for. 

best regards Peter Petersson

Reply all
Reply to author
Forward
0 new messages