My Vue Experience after 3 projects in 18 months
Hello developer pal!, glad to see you here.
In this post, I'll share my experience after 3 projects written/maintained in Vue 2.* during the last 18 months.
Show Me The Topics
The topics to be focused on are:
Agile Methodology and frameworks used
Design Systems
Infrastructure
Backend
State Management
Frontend
Disclaimer: This post comes from my own experience during this lapse, not saying this is the best way to go, nor the worst, any contribution is more than welcome in the threads below!
Agile Methodology and Frameworks used
Are you familiar with Agile Software Development?, cause I really am right now!, I really like this simple sentence as a summary:
Agile is the ability to create and respond to change. It is a way of dealing with, and ultimately succeeding in, an uncertain and turbulent environment.
- Source: What is Agile?
Nice, simple, straight to the point, isn't it?, during the last year and a half my teams passed over 3 different of its frameworks:
Scrum: from my perspective, the most interesting, this framework allowed our cross functional team to interact as a whole, splitting the work up in 2-weeks sprints, and constantly adjusting the business requirements, it is a quite nice experience!, highly recommended.
Kanban: my second favorite from top to bottom, a good option when the work to be done does not follow the same path, for instance working on different repos at the same time(MonoRepos, MFEs, Legacy Systems)l; when this happens perhaps Scrum is not enough cause the time-frames.
Extreme Programming (XP): required for an MVP one of my teams had, from my experience, the most risky one since you dynamically change requirements and some heavy lifting could magically appear/disappear down the road, highly not-recommended unless it is "Extreme"-ly necessary(pun intended), and please be "Extreme"-ly cautious(pun intended X2).
In case you want to read about the Agile Manifesto
(the corner stone of the methodology) you can do it right here.
Design System
I learned that after defining the Methodology, it is good to have a robust Design System
, you have 2 options: reuse an existing one or create one custom from scratch, either way the benefits are amazing!, when present it covers up 3 different areas:
-
UI/UX
does not repeat itself -
WebDev
has one-and-only-one source of truth -
QA
can evacuate questions on its own
In case you want to have some existing guide lines, here you can find a list of available resources on the wild.
In the teams I was working on, those where custom, a recipe for success was:
A great strategy that we found was to create Vue
components using Tailwind
and creating its respectives stories on Storybook
; I can say this is a great approach cause you can define your Design System
in Storybook
itself, and publish this to an accessible page for all your team members(under a VPN is even more secure), so it is available for everybody, they can see the components running in an isolated scope before even implementing it!
Infrastructure
Oh right, we had the Methodology and the Design System then what?
I learned that here it comes the Infrastructure
, well the approaches we had the opportunity to work with where Jenkins, TravisCI and GitHub Actions.
For experience, in big projects, Jenkins
is a great way to go, among all its pros, you can set it up for running on your behalf the unit testing and end-to-end testing before deploying!, in case of failure you are notified and a fix can be included.
In small projects, or side projects, you can use the TravisCI + GitHub Actions approach; GitHub
already has some built-in options for setting up ymls
and help you with Merge Requests and Deployments.
Note: TravisCI gives you 10,000 builds for free with your sign up, for small projects, proof of concepts or side projects it is a great deal!.
Backend
Also I learned for these projects, that a Backend
on NodeJS and Firebase is easily handle.
NodeJS + Express give you the chance to handle the routing for CRUD operations, it is easy to handle the request/responses.
Firebase is ready to go as soon as you import it in your Vue project; with a few lines of code you are able to do a lot!; Authentication, Storage, Realtime DB, a whole bunch of options are available for you.
I wrote non-canonical series related to some Firebase features if you want to check them.
State Management
I learned about VueJS + Vuex. I'm used to Rxjs, NgRx but Vuex is from my experience the easiest; with a little of knowledge you are able to start creating on your own, the separation of concerns through modules, and the way to reference then is crystal clear:
store/
├── index.js
└── modules/
├── module1.store.js
├── module2.store.js
├── module3.store.js
├── module4.store.js
└── module5.store.js
Referencing the modules in the index.js
make them importable through out your project, this includes State
, Getters
, Mutations
, Actions
; a new module is just the addition of a new entry in the index.js
, a deprecated module is the removal of that entry(conditions may apply).
I also learned that you can namespace
the modules!, then you can differentiate the elements by module instead of having dozens of lines with no context(trust me, with several modules this is amazing for debugging purposes, scalability and visual sake).
A clear example can be found below:
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex';
export default {
computed: {
// Accessing root properties
...mapState('my_module', ['property']),
// Accessing getters
...mapGetters('my_module', ['property']),
// Accessing non-root properties
...mapState('my_module', {
property: state => state.object.nested.property,
}),
},
methods: {
// Accessing actions
...mapActions('my_module', ['myAction']),
// Accessing mutations
...mapMutations('my_module', ['myMutation']),
},
};
It doesn't matter how small or how big is your project, it will be ready to scale, you can read here a bit more about Vuex and Namespaces.
Frontend
I learned that Vue
has a smaller learning curve than Angular
, and it is very similar to React
(Note: assuming you have a strong base of Javascript, otherwise the curve is high on either of them).
As a dev who was mostly involved in Angular
projects, understanding the core concepts and starting to be productive was easier than expected; I really think that the other way around must be harder, cause Angular
has its own world.
Also learned about some core concepts that made my development faster and easier:
-
Atomic Design Pattern: structure your folders as =>
- Atoms: these are basic components, dummy ones; could be buttons, inputs, dropdowns, any imagiable component small enough to be functional and testable
- Molecules: a group of Atoms, at this level just a little logic included, it should not include communication with you state(if possible)
- Organisms: mixture!, can have Atoms and Molecules, at this tier communication with you State can be allowed; Mappers, Getters, here are accepted
- Templates: here you add together the aforementioned structures
- Pages: every page you add is an instance that can be accessed from your routing strategy
- Vue Lazy Routing: it is trivially easy to lazy load the route components; after defining your routerOptions in 5 lines of code it is set and done.
import Vue from 'vue';
import Router from 'vue-router';
const routerOptions = [
{ path: '/', component: 'Home' },
{ path: '/home', component: 'Home' },
{ path: '/auth', component: 'Auth' },
{ path: '*', component: 'Auth' },
];
const routes = routerOptions.map(route => {
return {
...route,
component: () => import(/* webpackChunkName: "{{route.component}}" */ `../views/${route.component}.vue`),
};
});
Vue.use(Router);
-
Vue Test Utils:
Vue
has its own utils for testing purposes, and it is quite easy to understand and use, let me show the most simple sample I found:
<template>
<div class="modal" data-test="modal" aria-modal="true">
<div class="modal-content">
<slot></slot>
</div>
</div>
</template>
import { expect } from 'chai';
import { shallowMount } from '@vue/test-utils';
import BaseModal from '@/components/atoms/BaseModal.vue';
describe('BaseModal', () => {
context('Template', () => {
context('existence of the element', () => {
it("should exist 'modal' element", () => {
const wrapper = shallowMount(BaseModal);
expect(wrapper.find("[data-test='modal']").exists()).to.equal(true);
});
});
});
});
-
Global Registration of Components: There are components widely used, these are candidates to be registered globally so they can be referenced without importing them.
An easy way to accomplished this is creating a
_globals.js
file and fill it in with:
// Globally register all base components for convenience, because they
// will be used very frequently. Components are registered using the
// PascalCased version of their file name.
import Vue from 'vue';
// https://webpack.js.org/guides/dependency-management/#require-context
const requireComponent = require.context(
// Look for files in the current directory
'./atoms',
// Do not look in subdirectories
false,
// Only include .vue files
/[\w-]+\.vue$/,
);
// For each matching file name...
requireComponent.keys().forEach(fileName => {
// Get the component config
const componentConfig = requireComponent(fileName);
// Get the PascalCase version of the component name
const componentName = fileName
// Remove the "./" from the beginning
.replace(/^\.\//, '')
// Remove the file extension from the end
.replace(/\.\w+$/, '');
Vue.component(componentName, componentConfig.default || componentConfig);
});
After that, just import that file in main.js file:
import '@/components/_globals';
Some other good practices can be found:
Conclusion
As shown above, I had a long way during the last 18 months, I'm giving my two cents in here in the way I understood the concepts, and what I think were the best practices applied; maybe you could have a better way to do it, let's discuss in a thread below!
Thanks for reading!
Top comments (9)
It's amazing the coincidence of this post with the situation I'm going through. I'm also doing my third project in Vue + Tailwindcss at the company I'm currently working on and also plan to create my own components as a lot of things repeat themselves.
Got any stuff on how to create vue components using tailwindcss?
Not to be honest, you can create the Vue components the way they fit you the most, then add Tailwind however you want to, it is completely up to you..
My biggest issue with Vue2 after developing an medium size app in 9 months is lack of Typescript support and quite small ecosystem when it comes to ui libs or components. Bonus points for fantastic docs and really helpful community on discord. It's great that we have some kind an alternative for React. I'm looking forward to check Vue3 once it is production ready with UI libs Vuex and Router.
Thanks. If Vue would an official React Native module, will be very very complete.
You can try NativeScript nativescript.org/
There is Vue Native for now, but it still transpiles to React native. Another option would be to use something like Ionic Vue.
vue-native.io
ionicframework.com/docs/vue/overview
Awesome! I have a question, Is there any advantages by creating your own component using tailwind than using ready made components provided by some component framework of Vue like vuetify and quasar ?
Speaking from 1.5 years working on the same large vue project I would say that if you have the time(budget) to create your own components, you'll benefit from a very fine tuned custom look and better performance, which can be worth it in the right situation. However, 9 times out of 10 going with vuetify has saved us alot of time and made the whole process easier. We've identified some areas where custom components would help, especially where video and document editing are a focus, but our plan is to wait until our user base grows and we get more funding. Hope that helps
R(from FB) /
Hey sir!, good question, well 2 out of 3 projects were already using that approach when I started to work there, kicking in and redefine the methodology is not quite easy 😅, in the 3rd, it was a side project on my own, and I wanted to create something on my own cause the experience, it's been a gret way to understand, Im the sort of person who learns applying, so the advantage was mostly that...