What Javascript tool to use with Phoenix - where we don't have to replicate models, validations, a router etc

So we are building an questionnaire system at work using phoenix. We’ve been using phoenix channels to open a connect to the backend and we use that to answer the questions on the questionnaires. Our frontend is pretty basic using ES6 and jquery. I’ve followed a few different examples to allow our frontend to have page specific javascript and that is working well, but we are starting to see more complex logic being pushed into the frontend and I’m curious what others are using for taming the frontend if you will.

I’m really against adding a javascript framwork like react/angular/ect…

We don’t need the single page app funtionality or the templating that a lot of these javascript frameworks offer. I’m fine with server side rendering and EEx templates but we do need and want some type of javascript organization.

I’ve been looking into StimulusJS ( related questions I have on their forum ). This seems promissing and is more in line with what I’m looking for.

I’ve also seen a few posts in this community talking about intercooler.js which I’m not a huge fan of because we are already using phoenix channels which I think are better then ajax in our case (maybe?).

I’ve also seen a few mentions of unpoly that I honestly haven’t dug into but seemed complex from the outside.

Ideally I want something that I don’t have to replicate models, validations, have a router ect… in the frontend.

What is everyone else doing for this type of scenario?

2 Likes

Speaking of server-side rendering, have you looked at Drab?

2 Likes

I have briefly but from my understanding, and I may be wrong, Drab only helps if you have events on the server that you want to change the frontend with right? Most if not all of my “logic” is on the frontend at least right now.

Ahh I take that back, I just got done reading all of the tutorial section for Drab. That does seem to be something similar to what I’m looking for as well. I’d have to dig into it more to see how well it would work for us.

2 Likes

The way Laravel uses Vue is nice and also something you could copy with Phoenix.

2 Likes

FYI: Unpoly vs Drab
https://elixirforum.com/t/drab-vs-intercoolerjs/15230/3


We’ve been using phoenix channels to open a connect to the backend and we use that to answer the questions on the questionnaires.

I’m really against adding a javascript framework like react/angular/etc…

Just as a general observation - by choosing to use web sockets (rather than classical request/response) you are pushing towards more client-side rendering which tends to push towards a SPA-style with a client-side framework - not a hard-and-fast rule but there seems to be a tendency.

Our frontend is pretty basic using ES6 and jQuery.

Which suggest to me a general “fiddle with the DOM when new data arrives” type of approach.

I’ve followed a few different examples to allow our frontend to have page specific javascript and that is working well.

What have you be doing in particular? Because maybe all you need is something like a webpack multipage setup. The main benefit would be that you could use (ES2015) modules to “tame” your more complex frontend logic. jQuery distributed via npm should be well enough behaved to be used in a module/bundle environment.

jQuery/webpack example: How to Bundle a Simple Static Site Using Webpack

2 Likes

This isn’t a very good reason not to use it. Is this just personal preference or is there a problem you’ve encountered?

SPAs don’t do this. The front-end doesn’t typically validate very much and if you have a websocket connection to the backend to run validation for you theres little need to do so. As for the models, most SPAs just use a plain JSON object, so its just the data that comes from the backend and as long as that contract is not breeched everything is ok. Finally having a different decoupled router is a positive as you’ll want to organize your data access differently than your view layer may want to present it. You don’t want to be locked in to presenting your data in the way that its organized on the back end because that doesn’t always make the most sense to users.

These are opposites. Which is it? Keep in mind, for client logic heavy applications SPAs exist because its a more manageable way to write rich UIs. As mentioned before, the “fiddle with the DOM when new data arrives” type of approach is what leads to a lot of very difficult to find bugs and the reason why frameworks like React have taken off. Your approach can work fine, but it doesn’t scale well in terms of code maintainability.

2 Likes

This is an excellent observation, and I can see how this does have a tendency to be true. Replacing the request/response with a websocket immediately means you have to start writing javascript to handle the messages on the frontend. I’ll definitely keep this in mind.

Yes this is exactly what this approach feels like, which in general is why I’m trying to search for something better. At the very least in the organizational aspect.

Specifically I followed this: https://blog.diacode.com/page-specific-javascript-in-phoenix-framework-pt-1

I stayed with Brunch for now for the only reason because I didn’t feel like I needed to change it. I’m aware that Phoenix is going to be using Webpack as it’s standard in 1.4 I just haven’t felt the need to switch yet. That being said I haven’t done the research on the pros/cons of both.

But basically I have ES6 modules “mounting” per page and then I can put logic there.

The reason I’m against adding something like these frameworks is I don’t believe we need them right now if ever. It’s not a single page app we just have some complexity on the frontend with some of the UX experience. I’ve worked at several places where in the past a decision was made to build out the applications with these frontend frameworks and from my experience it has always resulted in more work. In general I think the whole single page app design is used more often then it is actually required. I’m not saying that these frameworks are bad but I’m just reiterating the fact that you should use the right tool for the job and from my experience a true SPA is rarely built that warrants these frameworks.

Yea I should clarify or restate what I said here. The “logic” I was talking about is things like hiding show elements, binding to events to submit the data via the websocket, binding to events to delete other elements ect…

The business logic is entirely on the backend, outside of the phoenix web layer.

100% agree with this statement. I think I’m still at a weird spot where I don’t think we need a completely rich SPA experience. I think we have a few basic UX experiences that we want across the site, in the examples I mentioned above. I’m really hesitant to bring in a large frontend framework to do some simple things. I’m looking for more of a general organization to keep things in order as we build out the MVP and understand more about the domain.

If after the MVP we find out that we need a lot more frontend functionality then I think that would be the time to look into some thing else, but even then I feel like personally I’d be hesitant. I just personally haven’t seen these frontend frameworks pay off. That very well may be that I haven’t worked on a team that used them very well, I’m not sure.

1 Like

Phoenix really doesn’t care whether or not you use a bundler or which one you end up using whether it is webpack, rollup, parcel, etc. But I think you have gotten to the point where you need to move bundler considerations from “necessary evil” to “prime asset of my development process”. Some of the key success factors in a modern JavaScript code base are well-managed ES2015 modules and transpilation.

JavaScript frameworks tend to “shepard” you towards certain organizational patterns and structures that reflect their philosophy or opinion. The problem with jQuery is that it doesn’t encourage any particular form of code base management - so in undisciplined environments this usually leads to no organization/code base management at all. So it may be time for you to spend some hammock-time to determine how you intend to use ES2015 modules (and I mean modules - not classes) in the future to keep your code base managable and maintainable. For some generic ideas have a look at Addi Osmani’s (pre-ES2015) Patterns For Large-Scale JavaScript Application Architecture.

I’d also be tempted to restrict jQuery use to certain tasks (i.e. DOM-twiddling which it is good at) and confine its use to the smallest (reasonable) number of support modules which expose their functionality to the other main modules via well-named functions. Use Vanilla ESNext where possible. Look into lodash or better yet Ramda to cut down on some verbose Vanilla JS (having a look at JavaScript Allongé, the “Six” Edition may not hurt either).

Nicolás Bevacqua (PonyFoo): Mastering Modular JavaScript

4 Likes

Lots of good stuff here @peerreynders, thank you! I’ll spend some time exploring more of this. I think this is exactly what I’m looking for though.

I had such problem when I was working on a Rails app some years ago. Most of logic was on server-side, including templates. Then I had a requirement for a page that required more complicated JavaScript. At that time I searched for simple solutions that can be used in only one page, without requiring heavy efforts of full frameworks.

I used Backbone.js, and I was happy with my choice. Gives you basic tools, like models, templates, routing and such, but doesn’t enforce you on anything. Have a look.

I don’t know that it’s advisable to start a new project in 2018 with Backbone.js - it’s had its heyday but the world has moved on. jQuery lingers because it makes the DOM-twiddling approach to web page interactivity so easy - but at least with some discipline you should be able to contain it’s impact (it’s just most people don’t bother with that - with predictable results). By adopting a framework - even something as minimal as Backbone.js - the framework gets to call the shots; so at this point it is important that one gets more in return for what is being traded off.

If one isn’t inclined to check out the (current) usual suspects like Angular (Google), React (Facebook) (alt: Inferno, Preact), Vue.js, Ember, Aurelia, etc. then Ebay’s Marko (Tutorial, Try online, Marko vs React) might be worth a look as a “modern lighter weight option”.

PS:

2 Likes

This may not be what exactly you want but I find it works quite well: Phoenix/Absinthe + React/Apollo/TypeScript

You can write GraphQL API with Absinthe, then generate schema from it, then generate TypeScript code (Model definition) and directly consume in TypeScript. It works because both GraphQL and TypeScript are statically typed.

With some command line stuff you can watch this process as you change the API.

And one thing I found about GraphQL is it kills most of my TypeScript/JavaScript, and left front end side mostly templates and styles like 10 years ago. (Of they turned into to a little bit of queries)

1 Like

Personally, I’m really enjoying Vuejs and highly recommend taking a look at it. You can use small amounts of Vue where you need it, without it taking over everything(SPA land) and without needing npm/webpack etc. I’m currently using it in Rails to provide some nice UI effects with transitions and give structure to the front end JS. I also like using a vue instance as a front end event bus when it’s helpful. I think Vue is a really nice and simple and structured solution to creating a slick front end and gave settler on it for my Phoenix apps in the pipeline. HTH.

2 Likes