0% found this document useful (0 votes)
40 views17 pages

A Guide To Fixing

The document discusses debugging techniques for Vue.js applications. It covers setting up the proper tools like the Vue.js devtools browser extension. Common error types are explored along with strategies for debugging like incremental testing and binary search of commits. A hands-on tutorial is provided where the reader builds a sample Vue.js project to demonstrate debugging.

Uploaded by

castrow666
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views17 pages

A Guide To Fixing

The document discusses debugging techniques for Vue.js applications. It covers setting up the proper tools like the Vue.js devtools browser extension. Common error types are explored along with strategies for debugging like incremental testing and binary search of commits. A hands-on tutorial is provided where the reader builds a sample Vue.js project to demonstrate debugging.

Uploaded by

castrow666
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Blog Web Development

Updated on Mar 21, 2022

Debugging Vue.js: How to


Fix Your App’s Frontend (w/
Tutorial)
Maxime Laboissonniere
Developer

A significant productivity milestone in my programming career was learning


to debug correctly.

They do tell you it's important at school. But like programming, you won't get
better unless you put in the hours.

Debugging happens at all stages of the dev cycle. Be it when you develop
from scratch, maintain or refactor code, you'll need to debug.
We will mainly use Vue.js in this post, but some of the tips are broad enough
to apply in any dev context, even to life if you squint hard enough.

Blog what
Here's Web Development
we'll explore:

1 The tools needed to debug your frontend


2 Types of error classes you'll encounter
3 The best strategies to use
4 Hands-on Vue.js debugging tutorial

So open up your RAM-consuming browser, and let's start debugging!

Ain't no fools with tools


(tools to debug in Chrome)

The first thing you should do when working on any project is setting up the
proper tools. The tooling is obviously tied to the tech stack. It might seem
trivial for a small project but monitoring your dependencies is crucial at
scale.
My definition might be too broad, but I would define tooling as anything
offering extra capabilities to working with a given tech. Adding font ligatures
to VS code (banal, but so worth it)or using a whole observability framework
Blog Web Development
are different kinds of "toolish" flavors.

As mentioned, setting up your tools should be done before debugging.


There's nothing less tempting than zooming out and starting to fine-tune
your toolbelt after finding a bug.

For our demo, we'll be working with an IDE and a browser. I am using VS
Code as my IDE, so I installed the Vetur extension on Chrome, which, among
other things, formats single file components.

You could further customize VS code and debug directly inside the IDE, but I
prefer doing so in Chrome. If that's a path you want to explore, you can read
more about this here.

As for the browser, I am using Chrome and will be using the Vue.js devtools.
With this extension, you will be able to inspect Vue components directly,
peek into the router, and time travel through your state history. It will save
you much time if you work a lot with Vue apps, believe me.

If you're new to Vue, consider getting familiar with the basics here:

Vue.js introduction
What is Vue.js?
Vue.js explained in 100 seconds (video)

Debugging error types n'


tricks
Much of the errors you will encounter will be due to:

→ Objects you’re accessing have different types than you thought.


→ Some values are simply missing.

Like when you think you're working in numbers, but you actually have the
Blog "42".
string WebMuch
Development
of these errors can be fixed by extending JavaScript with
languages such as TypeScript, but we'll keep that for another conversation.

Another common issue:

→ Something that doesn't act like you thought it would

This could be language primitives or libraries. Heck, the hours I lost using
array functions the wrong way are probably in the double digits. It's hard to
know unless you explicitly research the expected behavior. That's why
reading docs is so essential.

If you still haven't found your bug after looking at these two problems
classes, then your issue might be in your business logic. Meaning you are
just not doing what you have in mind. A trivial example would be that you
want to add two numbers, but you are subtracting them. Here’s what I do
when I know I'll be working on more complicated business logic:

I start by writing it in isolation, meaning outside the app it will live in. A neat
tool to do so is Quokka.js. It lets you spin a REPL like JS runtime that makes
prototyping instant. You can access variables values instantly and directly in
the IDE.

If you're a junior developer, one of the most common mistakes you will make
while debugging is to be convinced that the error is an advanced business
logic one.

Rule of thumb: errors are often less complex than we


presume. Always start with the dumb stuff. Reason with
types as much as you can.
The debugger's playbook
Blog
Debugging Web Development And you will only get better by actually doing it.
is programming.
There are no shortcuts. That being said, there are some general debugging
strategies that you should know, and experience will teach you when to use
them.

Before we jump in the strategies, there are at least two helpful things you
should know:

1 Logging.
2 Attaching to a process.

For this post, we are only interested in Vue.JS debugging, which lives in the
frontend. In that case, logging is done with the console object, and attaching
to the process is done by using a debugger statement.

You'll be using the console console.log function over and over. A neat trick
that I learned early on is that you can log multiple objects with one call. You
don't have to "stringify" and concatenate all your objects. You can do a single
call like the following:

console.log("Here's some text and an object:", {'prop': {'nested': 'val

The other thing you need to know is to bind to the runtime. It is done simply
with a debugger statement. Then you can read instruction by instruction.

These two methods let you inspect the state of your objects at runtime. It is
crucial since you will make mistakes if you try to compute this cognitively.
Now that you're armed with general error types and peeking methods in your
app let's check some general strategies to pinpoint where your errors are.

Incremental testing
Strategies depend on the developing context of the bug. If you are
developing something from scratch, you want to test it along the way
incrementally. If you get an error, you know it happened between the last
Blog Web Development
time you tried and now.

Binary search-inspired technique


If you just found a bug on an existing project and know it's relatively recent,
you can use a binary search-inspired technique by rollbacking commit. Let's
say you know the project didn't have the bug 40 commits behind; you can
rollback 20 commits and check if the bug is present. If it is, you know the
bug got added between the 40th and 20th commit; otherwise, it's in the last
20.

You repeat this until you get the exact commit where the bug got introduced.
The plus value of doing this? If you find the actual commit where the bug is,
it should be reasonably easy to fix if your commits are granular enough. This
process might seem heavy but, in practice, you'll probably have an intuition
about where the bug lies, and you might not need to split the commit history
in half blindly.

This technique can be repurposed for logic also. It's one of the most known
techniques in debugging called divide and conquer. You run your code until a
chosen breakpoint. You check if it acts without the bug. If it does, the bug is
in code further than the breakpoint and vice-versa. You repeat until you find
where the bug is.
With only these two general strategies, you can go a long way. You'll still
need to get your hands dirty and look around. Remember the three error
types and throw some logging & debugger statements around.
Blog Web Development
You'll develop a good hunch over time.

One thing you must always remember is not to self-sabotage. After


debugging the same problem for a while, you kind of get into a zone. Not the
good one, the anti-flow zone. This state makes you hallucinate error
proximity; you think the error must be so close since you've been working for
so long.

Instead of working from first principles, you try brute-forcing your way out. If
you can see yourself slipping in that pattern, take a break. Talk to someone,
it can be a rubber duck, and revisit the problem after. I can't even begin to tell
you how much time you'll save.

Tutorial: how to debug


Vue.js?
To make things a little more concrete, we will scaffold a small toy project
using the Vue CLI & the tooling we talked about earlier.

To do so, run the following commands:

npm install -g @vue/cli


vue create hello-world

Select the manual configuration and choose the following options:


Blog Web Development

You can keep the default options for the other prompts. Now go ahead and
boot up your project with:

cd hello-world
yarn serve

The stack we instantiated will most likely be the one used for any
medium/large Vue projects. Vuex is here for your state management and
vue-router for routing.

We'll add a state and some actions to Vuex to play with our tooling a bit.

Let's start by changing the Vuex store with this:

export default new Vuex.Store({


state: {
todos: ['The default task']
},
mutations: {
addTodo(state, todo){
state.todos = state.todos.concat(todo)
},
removeTodo(state, idx){
state.todos.splice(idx, 1);
}
},
actions: {
Blog Web Development
},
modules: {
}
})

And let's swap the Home.vue component for this:

<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">

<div>
<input v-model='newTodo'>
<button @click='addTodo'>Add todo</button>
</div>

<div v-for="(todo, idx) in todos" :key=idx>


<span>{{todo}}</span>
<button @click='removeTodo(idx)'>X</button>
</div>
</div>
</template>

<script>

export default {
name: 'Home',
data(){
return {
newTodo: ''
}
},
methods: {
addTodo() {
this.$store.commit('addTodo', this.newTodo)
this.newTodo = ''
},
removeTodo(idx){
this.$store.commit('removeTodo', idx)
}
},
computed: {
Blog Web Development
todos(){
return this.$store.state.todos;
}
}
}
</script>

Now, you have a bare-bone to-do app that lets you add and remove to-dos in
the frontend. Let's add and remove a couple of to-dos and check our Vue
extension.

We'll start with the Vuex panel. From there, you will see all the
actions/mutations that have occurred in our store. We have access to the
state at the time a given action/mutation was committed. It gives you the
opportunity to time travel and see your state at any given point. This way,
you don't have to reproduce by hand the same order of events to reach the
bug. You can do exactly that within the tooling, which saves you some
cognitive space.

You can also recommit actions to the store and "rebase" to a previous state.
This way, you can find where the state becomes faulty and dig into the last
action that made it so.

A little more advanced technique is the import/export of the state history. It


could become convenient if you were to debug someone else's problem
remotely as you could be asked by support. You could import their state
history, look at past states and isolate the one where it went wrong.

If Blog Web
you open ourDevelopment
little app and add some tasks and try to remove one, our
remove button isn't working. What a neat little mistake to test our newly
acquired knowledge. If we open our console and check our new Vue debug
panel, you will see something like this:

You can see we added two tasks by committing two "addTodo" events to our
store. Then, we committed a "removeTodo" one. Although, as you can see by
switching between the last "addTodo" and "removeTodo" events, the state
remained still on the later event.

Now, we would have picked up the error because the UI wouldn't have
updated, but some errors are much more subtle. It can be quite hard to track
them when, for instance, they fail silently. In that case, integration tests
could be the right way of catching them.

But, what exactly is happening here?

Errors aren't thrown in the console, so we're not accessing non-existent


attributes. The example is a tad contrived, but let's dig as we would have
otherwise. We know, thanks to our tooling, that "removeTodo" doesn't act as
we intended. Let's add some logging to see the actual behavior of our
function. Let's switch our "removeTodo" handler for:
removeTodo(state, idx){
console.log(state.todos, idx)
state.todos.slice(idx, 1)
Blog Web Development
console.log(state.todos)
}

And the output:

We see now that both our parameters, the state, and the idx , have the
proper values, but the state is never mutated. Now you should ask yourself,
“should I be mutating the array or returning the new state?”

A little dive in Vuex, and you'll confirm that you should be mutating here.
There's only one place to look now! Is slice mutating the array!?

A glance at Array.prototype.slice() will confirm that it is not.

It "[…] returns a shallow copy of a portion of an array into a new array object
selected from start to end ( end not included) where start and end
represent the index of items in that array. The original array will not be
modified."1 By looking further, you'll realize that the function you had in mind
was .splice() . Let's fix this and give our demo another shot.

1: MDN contributors

We could have achieved the same result by using a debugger statement


instead of logs. This example is relatively simple, so there's not much
difference. Although I found that I instead use logs for errors with time, I'm
not quite sure where to look at yet; while I prefer debuggers for errors, I know
their approximate location.
Blog Web Development
Here's now a working example of the state history after adding two to-dos
consecutively and removing one after. You can see the payload of the
committed action and the state after processing it.

Another important part of the extension is the components. It lets you look
at the component tree and expose the local state of each component. It
includes everything you would have in the script tag of your single file
component, such as data , computed , props , etc. I find myself using this tab
mostly to verify that props have the proper values and manually mutate local
states to make sure edge cases and run ad hoc tests.

Closing thoughts
When debugging, a lot of work is actually done beforehand by healthy
monitoring of your tech stack, enabling you to use the perfect tooling.

Blogwhen
Then, Web Development
actively debugging, never forget the tango between getting your
hands dirty with console logs and using your brain to think about what kind
of error types could explain your observations.

As with anything, the more you do, the better you'll become.

Happy coding!

If you've enjoyed this post, please take a second to share it on Twitter. Got
comments, questions? Hit the section below!

About the author


Maxime Laboissonniere
Developer

Max was the first dev hire for Snipcart back in


2016. Since then, he has stood out by his curiosity
towards new technologies. He’s the one that
introduced the team to Vue.js, for instance. In his 4
i d l h ’ t d
years experience as a developer, he’s mastered
JavaScript and its ecosystem, as well as C#.

These days, he likes to explore Elixir, Clojure, ELM,


Blog Web Development
RxJS, and data science--when he doesn’t have his
nose in a book.
Follow him on Twitter.

Build an E-Commerce Site with Wyam,


a .NET Static Content Generator
Read next from Maxime

View more
Blog Web Development

Recent articles
in Web
Development
Mar 23, 2022

The 6 Best JavaScript


Frameworks to Use in 2022

Diego Salinas Gardón


Content Strategist and Jamstack Community
Creator

WEB DEVELOPMENT

36 000+ geeks are getting our


monthly newsletter: join them!
Email Count me in!
Tutorials & editorials Product updates

Blog Web Development

Terms of Service About Snipcart Contact Status Français

Stalk us here :

© All rights reserved, Snipcart inc. 2023

Built in Canada

You might also like