Building an Enterprise Application with Vue

Applying Principles of Clean Architecture to Enterprise Frontend Application. Part 0 (Overture)

Greg Solo
JavaScript in Plain English

--

Dependency rule illustration for FE application

Preamble

In the last post, I was talking about different intricacies that may occur if we are not careful in separating the business logic of the application from the UI. But it was rather a theoretical monologue. This time I’d like to go one step farther and provide a tutorial on how we can achieve this goal.

As the title states, this tutorial is specifically about Vue implementation. I hope I will be able to find a time and prepare a separate tutorial for React. But since these two libraries are almost identical and since the core idea behind the approach is the same, I hope that React developers will find this post useful too.

Agreements

Photo by Cytonn Photography on Unsplash

Frontend development, like any other human practice, has a wide variety of approaches, techniques, even subjective preferences. Before we start, I would like to provide a few clarifications about the methods and techniques I choose to use in this tutorial. It is your right to disagree and prefer others, but I will spend a few paragraphs explaining my reasonings.

This is about building an enterprise application

The architectural ideas and approaches I am about to discuss are mostly applicable to enterprise-level applications. By this, I mean software that:

a. has quite a lot of complexity;

b. is built and supported by a team of developers (not one, not two but a team);

c. must stay alive for at least a few years and be as independent as possible from rapid changes of the frontend-world on one hand and be maintainable one the other;

d. is a web application: not a “thin-client” website, where almost entire business logic exists on the backend side. Nor is it a UI-library, which arguably contains no business logic whatsoever. For these cases, another approach would make more sense, I believe.

Test-Driven Development

I firmly believe that TDD provides a lot of value for improving code quality. Unfortunately, most of the tutorials I’ve seen do not use it (unless these tutorials are actually about TDD). In this post, I will be using a test-driven approach: we will first think about the tests of particular functionality, and only afterward, we will write the actual code.

Prerequisites

Photo by Sharon McCutcheon on Unsplash

Before we start, please make sure you have a few tools in your toolbox.

Understanding of component-based architecture in general and Vue specifically:

  1. you know what a “component” means in terms of UI
  2. you understand the basic syntax of Vue
  3. you know what “state” is
  4. you know what “render” and “lifecycle events” are

Understanding of Vuex

  1. you are familiar with flux pattern
  2. you know what “actions” “mutations” and “store” are
  3. you understand the connection between Vuex and Vue

Object-Oriented Programming

And most importantly, you know OOP and basic principles of good software design: SOLID, design patterns, separation of concerns, etc., etc. If you believe that javascript must support only functional programming, or that “OOP is for java devs”, this article will probably disappoint you.

Tools

Photo by Jo Szczepanska on Unsplash

Apart from Vue/Vuex, there are a couple of items in the toolbox that I’m going to use in this tutorial:

  1. TypeScript. We are about to start an enterprise application. Multiple developers will support it for a few years. Many developers who start the project will be replaced in a few years. This is the reality of the industry. Strict types (combined with decent test coverage and linting) provide a great way to reduce the maintenance cost of the application in the long run. I won’t spend time here on convincing you why this is so important. Fortunately, there are hundreds and hundreds of posts about it.
  2. JSX. Vue, by default, embraces a template syntax, which is subjectively much more “natural” and much closer to traditional HTML than JSX. However, the latter one has a surprising benefit: it supports strict types. I recently published an entire post about why this is important and how you can use it.
  3. Jest. I’m going to use Jest for unit testing in conjunction with Vue-test-utils
  4. Vuetify as UI Library

Project overview

Photo by Craig Cameron on Unsplash

This project will be a minimized, mocked version of a typical colossal enterprise app. It’s quite common to use Blog as a dummy project, and I’m going to follow this tradition.

Our Blog will naturally have Articles that users can read and Comments they can leave. It will consist of only two pages: Home page (contains a short version of and links to all articles) and Article page (full content of one singular article, comments that people already posted and form for posting a new comment)

Working demo is at your service (please pardon Heroku’s long warmup)

Source code

“Talks are cheap, show me the code”

Linus Torvalds.

Absolutely agree, so if you don’t want to spend time reading any further, feel free to jump right into the code

How to use this tutorial

The repo contains a few branches, each one for every chapter of the tutorial. Feel free to jump between them to see how source code slowly evolves with time. At the beginning of each episode, I’ll support you with the link to the specific branch for the section so you can follow examples step-by-step.

We’ll analyze the requirements we have to fulfill in this chapter. Then we’ll write a few tests to cover these requirements followed by actual code. And finally, we’ll wrap up with more tests or will fix the old ones if it is necessary: utilizing good old TDD.

First, check out the source code of the repo if you haven’t done it yet. Then, switch to the branch named “init”. It will put repo in the initial state, with almost empty project. Let’s take a look at the folder structure first.

  • “entities”, “services”, and “store” will hold respective elements of the app; they are empty for now.
  • “ui” folder contains things that usually are boldly put directly into the src: Vue components, router pages (or views), and Vue plugins. We know that UI is not important, so it feels right to place them under a dedicated subfolder.

I build this app on the shoulders of the vue-cli project. So, if you check package.json, you can see familiar commands like “vue-cli-service serve”.

To run dev server, simply use “npm run serve”. To run tests: “npm t”, in watch mode: “npm run test:watch”.

Please note, that I use quite strict ESLint rules for TypeScript: I enforce explicit function return type (except for expressions and Higher-Order Functions), prefix “I” for interfaces. I also forbid non-used variables and useless constructors, semicolons, and double-quotes. It is my personal (partially subjective) recommendation. It is up to you to follow or ignore it in your real-life projects.

Each step in each chapter will provide code snippets. You can copy-paste them and then run the project. But I would recommend to type them in instead. That will help you understand and memorize this code better and increase the efficiency of the tutorial.

Good luck!

Architecture

Last time I spend a lot of time talking about Clean Architecture in terms of frontend apps. Uncle Bob, in his article, gave a great illustration of the Clean Architecture. I took the liberty to illustrate how we are going to apply it to this project (the picture above).

This picture represents the Dependency Rule: the inner rings do not know the thing about the outer rings.

As you can see, in the center of the universe of the app are Entities. Those are core business rules (or even enterprise business rules in a broader case). They contain the most precious logic and are vital to the application — pure objects with zero dependencies.

The next circle represents Services. You can think of them as use cases for a specific Entity. It is the place where we fetch and manipulate them. Services follow the Dependency Rule and depend only on Entities.

And finally, a circle of details: not important, additional things like UI, DB (or the store), Frameworks, etc. They depend on Services and Entities as well as each other (component, for instance, depends on the store)

Without any further ado, here is a list of topics we are about to cover:

See you next time!

--

--

Software Engineer. Immigrant. Entrepreneur. I have been telling stories through software for 15 years in the hope to craft a better future