VueJS has gained some incredible and warranted traction over the past year or so. I’m sure at this point you are pretty tired of reading articles about “Vue passes React in stars on GitHub!” By now, we all know how great of a framework Vue is so there’s no need to belabor this point. Instead, I’d like to share my experiences at Veoci leading the migration from Vanilla JS and jQuery to BackboneJS (Veoci 1.0), and ultimately Vue paired with the component framework Vuetify (Veoci 2.0 — creative, right?).
Veoci started in the beginning of 2011 as the brainchild of our CEO Sukhminder Grewal and five other Co-founders. Veoci is a “no-code application platform.” This means users can build full-on solutions for their business needs with little to no web development understanding. Veoci provides tools such as chatrooms, GIS mapping, dashboards, tasks, forms, workflows and digital plans that can be launched with the click of a button. Users can assemble and combine these building blocks however they want to best meet their requirements.
To provide this experience, our code itself must be very complex to handle the myriad of incredible customer use cases. I am regularly surprised at the things people dream up with Veoci. Emergency response plans — you got it! Airport runway incursion reports — sure! Running an NHL playoff pick ’em pool — of…course? (That is a real use I put together using Veoci.) The customer use cases and the solutions they’ve dreamed up on Veoci are super broad and diverse; we could have never dreamed of these when we created Veoci.
When we started out, the web standards we know and love today were in their nascent stages. It was a simpler time where the HTML5 API was the new hotness, NodeJS was just catching on and frameworks such as AngularJS or BackboneJS were mere whispers in dark alleys, yet to see the light of mainstream adoption. I liken it to the pre-cambrian explosion period for web frameworks. A time before intense framework loyalty sharply divided the front-end community into competing camps. Of course the ugly duckling in the room known as IE8 (and below) was still heavily used. Thank the browser gods that is no longer true. No matter what your framework affiliation, I think we can all agree that was a good development.
Since we were in every aspect a bootstrapped startup (our desks and tables were literal doors velcroed to sawhorses), we didn’t have the luxury of experimenting with the “fancy” new web frameworks. So we decided to roll our own pure JS and jQuery architecture, since that was the battle-tested way of doing things at the time. That went pretty well for a quick second. However, as new requirements continued to pour in and our late night hack-a-thons layered on more and more complexity, it quickly grew incomprehensible and unruly. Six developers in a room throwing ketchup packets at one another to ask questions was not a viable long term strategy for building a complex application platform.
We knew we needed something to help us tame our application structure, so we began to experiment with some seemingly lightweight options. Unfortunately, all of them had their own problems that made things even more complex. The first one we tried to integrate circa 2012 was jQuery UI which had some nice plugins, but was not the prettiest looking library. It wasn’t really a framework as much as it was a UI library, and boy was it harsh on the eyes. Needless to say it didn’t stick. Then we tried to leverage Bootstrap. This looked much better but was far too opinionated for our application. As soon as we integrated it, things were broken beyond repair due to JS and CSS conflicts. That experience and subsequent CSS issues hastened my personal understanding of how to properly structure CSS. Plus the integration effort for these libraries was not worth any gains we might see.
The next solution we attempted was to sprinkle in BackboneJS components throughout the application. We realized that we should try to use some of the Backbone structural pieces such as the router as opposed to our custom built router. This went a long way towards helping corral our code, but it was far from perfect. Ultimately, we converted several of our pages entirely to Backbone, but it wasn’t enough. Backbone was very nice for spot improvements, but without further structuring it was not the solution.
The Turning Point
Towards the end of 2016, we were really starting to feel our growing pains. We had more customers than ever, an increasingly complex code base, a full-featured mobile app to maintain, and a steady influx of requests for new enhancements and features. It was a lot to manage. I was venting with our Mobile Lead at a bar one night and we realized the problem was we needed to rethink the very foundation of the custom JS architecture we rolled all those years ago. Layering some additional structure on what was there would be a massive project, and ultimately not gain us very much.
The first time I played with Vue, I thought I was doing something wrong — everything was so simple and straightforward
I spoke with our CTO, Dan Dormont, and we decided the first step that we needed to tackle was to reinforce basic code quality standards. Plus I desperately wanted to take advantage of some of the modern ES6 syntax that was introduced. That was when I began to adamantly push for some modern tooling to be set up for our dev environment. I led a project to convert our entire RequireJS loading structure to Webpack to bundle our code. As part of this, I spec’d out some Eslint code standards and Babel to transpile our ES6+ code into something that would work everywhere. Around that same time, I moved our tests into a dedicated CI environment using CircleCI to make sure these new standards were vigorously imposed. This was all great, but it didn’t actually solve very many of the issues that we had.
Enter VueJS and Vuetify. The first time I played with Vue, I thought I was doing something wrong — everything was so simple and straightforward. I felt I was either getting away with something I shouldn’t be getting away with, or I was completely ignorant of something huge and it was going to blow up in my face later.
I had to keep going back to make sure I was actually doing it correctly and not hacking around stuff. Keep in mind that the only other framework I had seriously built things in for a large scale environment was Backbone, so this was quite a shock. Update a property and the UI updates with no complex bindings or DOM manipulations — Magic! I realize Vue was not the first framework to do this, but it just felt “right.” It didn’t have the hoops to jump through that other frameworks had. It felt like it took the best of its contemporaries and assembled them into a simple solution.
Now that we had settled on a language framework, we had to start coming up with some sort of strategy for integration and adoption. Initially, I worked with one of the other front-end engineers on a peer coding project to rebuild a few small components in the existing backbone structure to “prove” that Vue was really as flexible as advertised. The webpack migration we had done only a few months before enabled us to very easily drop single file Vue components into our backbone views, or simply replace some of them. This was so successful, our team decided that we were going to go all in on Vue.
However, our experiences of the past few years made us leery of jumping into a new technology without first coming up with an enforceable structure. This is where Vuetify has really worked well. We knew we wanted to create a true Single Page Application. Veoci 1.0’s page structure is actually pretty interesting. Currently, a bunch of discreet web pages which essentially function as small SPAs with unique routes and subroutes live inside the context of the larger parent wrapper. These child pages all load inside an iframe embedded in the parent frame, which contains a “fixed” masthead and the business logic for handling user presence persistence. Believe it or not, this was actually how Facebook handled their presences circa 2011. At one time, this was the new hotness. There is a lesson to be learned there.
Vuetify is a Material Design component framework which provides a number of easily adoptable Vue components strictly adhering to Google’s Material Design guidelines. These components contain a bevy of customization options which make them very easy to style to fit into our application theme. One of the biggest selling points of Vuetify was the ability to use these components “a-la-carte,” or as needed, without adopting the entire framework. Veoci is a growing business and an ever-evolving product — we couldn’t just stop new development while we burned 7 years of code and experience to the ground in order to rebuild everything from scratch using a new framework. Some phoenixes are not meant to be.
Where Veoci’s Headed
All that said, we knew that we couldn’t continue building atop a brittle foundation. In January of this year I began to aggressively push to rebuild Veoci in parallel to the ongoing maintenance and new enhancement development. I wanted to leverage all of Vuetify’s application structural components to the fullest, using the Vuetify webpack template as a starting point. It was quite eye-opening.
I could begin to focus more on the real goal — building cool new features — and less on not breaking anything while building them.
Imagine building a wooden deck with no blueprints and a hand screwdriver where your measurements were loosely based on how my Dad likes to measure things: with his hands, arms, and feet. After 7 years of working like that, suddenly someone introduces a full blown drill along with a set of explicit measurements on a blueprint. That’s what it was like when I started working on this new project. The metaphorical blisters on my hands started to heal and I could begin to focus more on the real goal — actually building cool new features — and less on not breaking anything while building them.
Not to mention the tooling was mind blowing. Hot reloading is not necessarily a brand new innovation, but the first time you work with it in an enterprise level setting no one would blame you if you shed a tear or two. It’s that big of a quality of life improvement. Additionally, the Vue debugging toolkit made developing with the components an absolute joy.
This is where those “a-la-carte” components mentioned previously come into play. Leveraging that feature allows me to build brand new features in the Veoci 1.0 application using Vue/Vuetify which can essentially be dropped into the Veoci 2.0 Vuetify application when the time comes and they are needed. This was critical for us to reduce the amount of duplicated work. It’s the perfect compromise for our business needs.
While there are not currently any compartmentalized components shared between the two projects, I have some imminent plans to spread them. I’ve been working with a relatively new project called Bit which is a service that allows you to package individual components into small shared repos outside npm to install in other projects. Ultimately, this would be ideal in the short term because it would allow us to build components in either project without the need to refactor them into yet another repository. Of course, that means integrating another third party service. Worst case scenario, we can go the tried and true route of creating a private shared npm repo each project can pull from as needed until we sunset Veoci 1.0.
If you enjoyed hearing about Veoci’s experiences, give a clap! Feel free to contact me on Twitter or LinkedIn if you’re interested in hearing more about the Vuetify project or Veoci in general. Also, keep an eye open for my next series about integrating “a-la-carte” Vuetify components into existing enterprise applications.
Veoci is hiring front-end developers! Visit http://veoci.com/jobs for more information on how to apply.