Modern Front-end in Rails
evilmartians.com
evilmartians.com
I wouldn't say this decision was made without careful thought nor without weighing many options. But when it comes down to it, many line of business applications (which is what I see a lot of in the market) don't need the level of sophistication the instructions in this article gives. Most applications need to be reasonably fast, reasonably responsive, and extremely easy to maintain and extend. Does working with all of these modern front end tools that change so quickly and given at least one order of magnitude increase in complexity also give the application a equal increase in speed, responsiveness, maintainability, and extensibility? I don't think so.
I'm not the first person to say this. Take a look at this presentation by Sam Stephenson, it will be worth your while: https://www.youtube.com/watch?v=SWEts0rlezA
Exactly this. I do a lot of freelance rails work and have worked on all kinds of ruby/rails projects. I would say for honestly at least 80% probably around 90% of projects, the "old school boring" rails way is by far the way to go. The whole front end heavy craze is really not the right choice unless you need a very high degree of desktop-like interactivity which again is something most i.e. 80/90% of applications I see in the wild do not require.
I prototyped something in a couple of days with Python and Flask and it made a good enough impression that we are thinking about fully developing the idea. I'm open to just about any tech and am thinking about continuing with Flask (and Flask-restful), using Go, or Ruby on Rails. I have almost no experience with any of these and that's part of the reason they appeal to me.
Even if it is a little excessive (which I don't think it is), I have features planned in the future where having an ORM like ActiveRecord+Ruby will make things very simple.
I'm a bit of a REST newbie and so some concepts (esp HATEOAS) are still a bit blurry. I would probably take a little time to dig into just what goes into a well-structured REST service.
I'm going to be honest with you. I love building pure REST apis in rails. The experience is so clean and effortless.
That being said there is at least one caveat to using RoR for the first time, and thats that the learning curve is probably going to be a little steeper than a rest lib like flask where things are more explicit, since there is a lot of convention over configuration in RoR. Once you learn the conventions, the development speed is ridiculously fast, but until then things can be pretty opaque and take some time to get used to, especially for people who don't understand well how the ruby runtime works. I've witnessed this on multiple occasions with multiple projects, if there are more advanced/not-stack-overflowable things that need to be done, devs who are working in RoR and ruby for the first time, will run into a lot of roadblocks. This has little if anything to do with their particular skills as a programmer and more to do with the dynamic nature of ruby and a lot of very tricky hacks rails does under the surface to make the end-user api clean and succinct.
Overall, we've seen a substantial increase in speed, responsiveness, and most importantly our ability to maintain and extend the application.
I applaud this approach and would love to have an opportunity to one day work at a company that values reliable and sensible approach to building software instead of just following the latest fashion.
As Mikey Dickerson said; what we need is basic, well-known technology, applied correctly.
But yes, it's nice that the world is finally realizing Arc was way ahead of its time. HN is snappy because the HTML is small, with few network requests.
https://rauchg.com/2014/7-principles-of-rich-web-application...
(Angular, less so, though these days I do appreciate it when companies are so kind as to list Angular in their job postings; it's a good heuristic for weeding out based on the probability that there's no one with influence at the organization that thinks about the tools they're using carefully.)
There’s no doubt I have had applicants pass on us because we don’t use one of those frameworks. But there are plenty of other great web devs who do want to work in a reasonable environment and love it. So it’s balanced out.
I’d say my greatest selling point for the job is that we deploy all day long to production. Developers love getting features to users.
This has got to be costing companies money, but it's hard to say when we'll see a return to simplicity as a virtue.
The joy of Rails is that for the most part you can just focus on getting shit done, focus on building value instead of figure out the right directory structure or which latest framework to use (learn) on your project.
I have yet to see a demonstrable benefit from the single page app, front end framework, microservice backend that I didn’t have with a Rails monolith 10 years ago. The majority of what I see these days is unwarranted complexity.
The two technologies play very well together and I've been able to add AJAX at the high value points in the app, rather than biting off a huge bit of infrastructure that needs to be maintained everywhere.
It's perfect for small to medium sized apps that need just a little bit of front-end sprinkling.
I get a lot of the benefit of a SPA (client side reactivity/UX/UI) with the benefit of a traditional architecture.
The "do it all on the server" vs "do it all on the client" approaches never made sense to me, do the bits that each is best at in the correct place.
It's extremely easy to get started with a front-end app using vue-cli. This article spends a lot of time changing Rails' default functionality to achieve behavior similar to what vue-cli gives you by typing `vue init webpack` and answering a few questions.
I understand that getting up to speed with a front-end framework takes time, but in my case, it was time well-spent (I used Maximilian Schwarzmüller's Vue.js course on Udemy). There's no shame in just using Rails for the API.
Clearly for the authors this is a usual workflow - they're productive with it, and they only had to pay the complexity cost once (when figuring out things).
Once you get an integrated frontend-backend system and codebase, you start to get unique benefits:
- Server-rendered data, for avoiding superfluous ajax requests
- Simpler deployments (fewer moving pieces)
- Single codebase, less knowledge segregation
and so on.
It's not a one-size-fits-all solution, but for a single dev / small team working on a web-only application it can make a lot of sense.
For anyone interested, Gorails has a series on Vue + Rails that's been very helpful. https://gorails.com/series/using-vuejs-with-rails
Not to mention, the combined approach is 100% necessary if you are going to require a server render for your react||vue|ember stuff.
Why’s that?
We as developers already offload certain tasks to separate servers. Do you use your app server to terminate TLS connections? You could; but why would you when Nginx can do a much better job of it?
You could store you application data like usernames and password in a JSON file if you really wanted to. But why would you when you can run an SQL server and use a real database?
Pick the best tool for each job. JS frameworks handle the view layer better than Rails does.
Faster? I don't see how putting an entire app server layer in between your HTTP requests is going to make anything faster.
More maintainable? You now have an entire codebase duplicating the request your client is making. It actually breaks SRP more than it helps, because you'll need to constantly keep it in sync with your rendering/client codebase in order to perform server rendering. The individual codebases may be more maintainable but your application as a whole now has fragmented responsibilities.
I can't imagine when the trade-off of introducing an entire new layer of infrastructure into your app in addition to your normal app servers would be worth it just for the purpose of server side rendering outside of some specific niche scenario. That sounds like overengineering to the extreme.
This is factually wrong. You have a small component that mounts your front-end like a pure function. No loss in maintainability, no "duplicate" anything.
That's two different places that logic must be deployed to and tested against. It's irrelevant that it's the same render code.
The only time I can justify SPA is if you’re primarily differentiating via the UX.
That is not true, you just call what you need from the JS framework and you can still use the old HAML in the other areas.
I've been working with Rails since 2006 and I'll create two separate projects. A Rails API project and a front end one. Two projects, two repositories, maybe two teams (specialized teams are more common than full stack.) The front end is served by the reverse proxy in front of Rails.
If I want to serve some semi-static HTML page from Rails, all I have to do is sharing the CSS file and create a controller for that (PagesController is a classic.) I don't think there are many chances of sharing HTML in a meaningful way among ERB and JSX, that must be duplicated.
Then Rails people will work with Rails tools and JavaScript people will work with the favorite tools of the month. The advantage is that if you want to onboard some pure front end developers they won't have to learn about Rails.
But it's article not for teams like this. The described solution for full-stack developers and small projects, which needs to be maintainable too. And component manner is a proper way to organize frontend code.
If you are beginner Rails developer who doesn't know how to configure Webpack properly and doesn't know how to works with React/Vue/Ember?
And if your project must be a SEO-friendly? You don't know React, Webpack and doesn't know how to works with React/Vue SSR.
Maybe learning its tools will be an excellent investment if you want to be a front-end developer. But what if not?
We wrote this article mainly for beginners full stack developers. They are not well-experienced front-end developers.
My project started more than four years ago. It was a mainly content project around content creating and sharing, and of course SEO.
Facebook released React two month early than we started. Webpack has not yet created. Gulp is a bleeding edge. And we used sprockets, CoffeeScript and SASS.
It's is a massive project now. And it changed development vector for last year. We make a lot of changes, and we haven't resourced for rewriting them on separated front-end and back-end for now.
But described methodology allows us to keep this project maintainable. We migrated this approach from Sprockets to Gulp, and from Gulp to Webpack.
And we thought. What if we tell about how we maintain the project to beginners? They are writing jQuery-spaghetti code, and they may don't know frontend frameworks and Webpack.
Let's tell them how to write maintainable code with webpacker, components, BEM and our code organization. It's maybe a good starting point for them.
SSR is indeed still a problem (I've build a cache system that will render pages with chrome headless, for that), but gladly, it's about to be solved (at least for the SEO part): https://webmasters.googleblog.com/2017/12/rendering-ajax-cra...
The biggest problem yet to be solved: properly handling 404 status.
Rails is awesome bc it’s opinionated but the fact that it’s ruby still lets you do what you want. I think rails needs to really dedicate some effort to better generators that ask which of these modern front end approaches do you want to use and then setup the project to just work and let me get to my coding.
This article seems a bit of overengineering by comparison and isn’t representative of what’s new out-of-the-box.
There’s also a new secrets mechanism of dubious necessity. Seems DHH just can’t stop reinventing those.
It's all great, I got my way around it, but I never know if what I'm doing is considered best practice or not.
https://medium.com/statuscode/introducing-webpacker-7136d66c...
> 1. isolated, reusable, testable code that is easy to reason
> about;
> 2. short “code change → visible result” cycle;
> 3. straightforward dependency management; and
> well-maintained tools.
> Sure, “classic” Rails gives our code some structure: there
> are separate folders for view templates, javascripts,
> stylesheets and images. But as the front-end complexity
> grows, navigating them quickly becomes a cognitive drain.
WAT?
1. I don't see how the directory renaming / npm config changes this at all.
2. I guess this is an argument for speed of asset pipeline? As mentioned in the article itself, Rails 5.1 webpack with hot reloading built in. How much faster can you get?
3. I don't think I've ever heard of npm referred to as a well-maintained tool.
Beyond that, the idea that Javascript-heavy web apps are "Modern" is kind of silly. They're certainly trendy. In the vast majority of the cases I've seen, there's no coherent reason for the added complexity.
There's also turbolinks-ios and turbolinks-android, I built my mobile apps with minimal knowledge of Swift and Kotlin.
When two or more things on the page need to know about each other/you require a high-fidelity interaction that you can't easily handle with just it, then yeah - reach for vue, react, or what have you. But no need to start there! Use those as targeted air strikes
At least, that's been my (very limited) experience with it.
Which is a shame considering how much it speeds most typical applications up by completely ignoring the mobile advantages.
For at _least_ 90% of the things out there, you don't need a front-end framework like React/Vue/Ember/Angular. And while these front-end frameworks increase the complexity of the app, its trade-off often doesn't nearly provide enough value in terms of speed/extensibility/maintainability to warrant it.
Rendering server-side views is fine: plug-in Turbolinks and have a blast. It's not cool, it won't get you stylepoints with your colleagues, but you should be trying to impress your client/boss with speed/extensibility/maintainability, and not impress with complexity of your stack.
Modern JS is lovely to write compared to ES5, but this tutorial doesn't write any yet! Perhaps this'll be addressed in the next part of the tutorial (although doing it in a framework-agnostic way seems tough).
Also, if I'm reading this correctly, they're still attaching an `erb` for each component, and using Rails to determine how they relate to each other? This feels a bit wrong to me, at least for dynamic web applications; when you have a framework like React controlling all of your front-end rendering, it's easy to integrate client-side routing and make it a single-page app, which means lightning-quick page transitions.
So yeah, delighted to see Rails move towards this direction, and this post is super helpful in explaining the "how" for a basic setup, but not the "why"; it also falls a bit short IMO in going "all the way", to have the front-end truly control its destiny and reap the benefits associated with that.
The method in the article seems like a very non-conventional way to go about it with no added benefit.
It sounds like your taking React's render() and replacing it with ERB. But, how are you giving the ERB file access to state and props?
I suppose if it's done well, this would make it easier for Rails devs to adopt single page apps. It sounds like you're abstracting away a lot of React and creating a Rails-ier API to it.
What's the purpose of making text small, punishing readers for not maximizing the site? :-)
Seriously, it could be a way to make text flow into a smaller column, but there is no need to make text smaller. HN reflows and keeps the same font size.
However, I have found precious few actual guides on the iOS and android wrappers. Has anyone found a good guide / documentation on this topic?
Django is comparable in scope but Rails is many times more popular and a lot more work has gone into it. IMO you would need a very good, specific reason to choose Django over the far more popular Rails.
Probably Meteor, though not as mature as Rails.
Most of all, I believe a set of good practices enforced or encouraged with Rails is what distinguish it over all other frameworks.
Most difficutlty with Rails is after few years when you need to upgrade, I feel a lot of busy work has to happen then.
When starting a new project, my major decision is if I want to use the REST API flavor of one of these frameworks + react on the front end (substitute with your front end framework of choice), or build the project fully in the framework itself. I've been writing a lot of python lately, so I go with flask for small or quick/dirty stuff, Django or Django Rest Framework for bigger stuff. React on the front end if it needs to be a SPA.
Who made you the grand arbiter? There are huge differences. Rails is miles ahead in the options you present. Probably 90% of startups that don't have a specific reason not to, use Rails - and rightly so.
Rails has over 65k commits. Django has 25k. Sails? Less than 7k. Don't tell me these are equivalent.
Ruby by itself is a powerful reason to develop with Rails.
The Rails team historically is known for making informed decisions about file structure conventions, since Rails already picked app/javascript as the place for webpacked JavaScript, why the need to move it?
Rails with webpacker built in and rails api mode are both awesome, but they don't feel well integrated together.
Sure, you can get this working in a rails engine, but it feels like a hack and you miss out on a lot of built-in template goodies. There is also shakacode's React on Rails, which is awesome, but still pretty tightly integrated with the default rails views.
http://www.castingcall.club serves over 1M pageviews a month. Total hobby project. It has a hybrid of what this article describes. I have my `/app/assets` folder for most of the pages on the site and I've got my webpack `/frontend` folder which handles the complex components.
I also run http://program.reforge.com. Same approach. Rails asset pipeline for the pages that are simple and React on the pages that need to be componentized.
First it shows you how to override rails defaults to create very similar environment that you would get if you would go api/react or vue. Advantage with this setup is that you still Rails foundation and this comes with a lot of goodies.
I love that it explain rather simple way to have hot reloading, I feel this makes me significantly more productive.
Overall really enjoyed article and will adopt many of ideas in it. It is good way to modernize your Rails projects.
One thing that would help me understand this better is a short overview of your strategy and why you chose it as opposed to some other options mentioned like rails api + JS-framework frontend.
It goes from history to nitty gritty, so I'd have to follow through step by step to get an idea how it all fits together.
This way I can produce either an app frontend (something that requires JS) or a site frontend (something that doesn't require JS).
Edit: Sorry for my harsh words. I just get kinda angry when I come across websites that don't allow me to zoom in or out, especially when the default font size is way off the standard.
It's been about ten years, and you don't see as many Rails posts as you used to, but it still holds true!
Am I missing some sort of joke?
(look in the 'computed' tab of dev tools)
Not every part of an app needs the duplicity of state, or need to look dynamic.
I can sprinkle in javascript for a normal rails app to add behavior - but i thought react required moving all rendering into it? are you able to "sprinkle" with react within otherwise normal html/css/js?
With React you basically let it manage one or more subtrees of the DOM; you let React do the rendering for that subtree at all times (possibly using React on the server to do pre-rendering).
I do think calling Rails' method classic and these new frameworks "modern" a bit ignorant. If anything Rails is "modern" and these new frameworks are just that, new. Being new does not mean you're modern. It means you're new. A trend. You'll likely be gone tomorrow.
That said, I think that frontend development has evolved into a place where frontend development is better done separately. As part of its evolution, Rails integrated Rails API and can be configured minimally to be a backend API only.