🔭 #2: Attribute Inheritance in Vue, The Temptation to Start from Scratch, My New Note Taking Approach, and More
Problems with automatic attribute inheritance in Vue 3, the urge to throw away old code and start from scratch, taking notes using an actual pen and a piece of paper, and more.
Hey,
Last week I explored the problems with multi-root node Vue 3 components and automatic non-prop attribute inheritance.
In my latest article here on Substack, I wrote about the temptation many of us feel when working with legacy code: throw away the old and start from scratch. But is this the best approach, and how can we withstand this urge?
I thought about how easy it is to test SPA’s compared to applications following a more traditional or mixed approach because it makes it necessary to solve mocking across technological borders.
Using pen and paper to take notes seems antiquated in modern times. Still, the last couple of weeks, I perfected my workflow doing precisely that: using an actual pen and an actual piece of paper to take notes.
Last but not least, I managed to use the Branch by Abstraction principle for the first time to do a major refactoring in one of my projects gradually, with great success so far.
This is the 2nd issue of my Recent Discoveries newsletter. If you don't want to miss the next issue, hit subscribe.
Multiple Root Nodes and Attribute Inheritance in Vue 3
A tweet by Manuel Matuzović reminded me that in Vue 3, we finally have fragments. But I also remembered that this is not without its problems.
<template>
<!-- ✅ -->
<SingleRootNodeComponent class="myClass"/>
<!-- ❌ No attr inheritance with multiple root nodes! -->
<MultiNodeComponent class="myClass"/>
</template>
<!-- MultiNodeComponent.vue -->
<template>
<div><!-- ... --></div>
<div><!-- ... --></div>
</template>
Automatic attribute inheritance is a nice convenience feature in Vue, which React does not have. But where there is light, there must be shadow.
Out of the box, it only works on components rendering a single root node. Although using class
on MultiNodeComponent
will log a warning to the console, it leads to a suboptimal developer experience when using MultiNodeComponent
.
I wrote an article about this very topic where we look into the problem in more detail.
References
The Temptation to Start from Scratch
A common phenomenon among developers is the desire to start all over again. Let's throw away all the legacy code and start fresh. This time everything will be better, we tell ourselves.
The best-case scenario is that we might avoid repeating the old mistakes but make new ones instead. However, the worst and much more likely outcome is that we create new problems and repeat many of the errors that led us to throw away our old code in the first place.
When we think about the fictional new and perfect code, we fail to consider all the nasty edge cases the old code could handle. We don't think of the many times that looming deadlines led to particular trade-offs. Let alone the fact that most people working on the new codebase have different opinions about how good code even looks.
If you want to read more about my strategies for dealing with situations like that in a more sustainable way, read my article about that topic.
Mocking Across Technological Borders
I spend a lot of time thinking about automated testing—most of my work centers around how to test classic SPA's. Tools like Cypress, Jest and Mock Service Worker are excellent packages to help with that. For example, thanks to Mock Service Worker, we can use API mocks in both Jest unit tests and E2E tests with Cypress.
Recently, I faced the question: how to test applications that are not (traditional) SPA's. For example, sites built with Laravel, Inertia, and Vue.js. Here the challenge is that the bulk of the data doesn't (always) come from an API, and there is no network request to mock. Instead, at least for the initial request, the data comes directly from the PHP (!) backend and is injected into the initial HTML response.
I have worked out a concept for solving this problem:
Cypress tests write mock files to a folder in the file system.
The PHP application provides data to the SPA via services that use repositories to fetch the data.
In test mode, we swap out the repositories with mock implementations.
Instead of accessing a database, the mocked repository implementations read the mock files in the file system created by Cypress.
I thought about this file-based solution instead of using a more traditional approach like DB seeding because I assumed that it would be easier to simulate various errors and successful responses that way. But maybe I'm overthinking it?
This probably doesn't sound very straightforward. Let me know if you are interested in an in-depth article. Or maybe you have already found a better solution yourself? I would be happy to hear about it! It seems to me as there has to be a better way to do this.
Pen and Paper Notes
This is not about the role-playing game but taking notes the old-fashioned way: using pen and paper. For the longest time, I was very much convinced that everything digital is superior. Maybe it is because I'm getting old, but I recently started to use an actual pen and paper to take notes (again). The results are fantastic.
My workflow is as follows:
When some raw idea crosses my mind, I take a fresh piece of paper and jot it down.
Then I put the piece of paper(s) somewhere (sometimes at my desk, sometimes on the couch, sometimes even in my bed).
When something related comes to mind again, I find the note and write it down. If I can't find it or I'm away, I write the thought on a new piece of paper to add it to the other sheets later.
At some point, when the idea has matured, I decide what to do with the notes: throw them away, transfer them to my knowledge base or maybe even write an article about them.
The last point is what makes pen and paper superior in my opinion: you have to do something with all those pieces of paper. In the digital world, you have infinite space. You can put your crude notes somewhere, and the next moment they're often forgotten. I've found that a process like that doesn't add much value. You end up with a massive collection of half-baked thoughts that you never look at again.
Branch by Abstraction
Branch by Abstraction is a technique for making large-scale changes to a software system in a gradual way. For example, imagine you have a messy or outdated component or library, but it seems impossible to replace it because we use this piece of code in hundreds of places in your app. By applying the Branch by Abstraction strategy, we can swap out the faulty code step-by-step. First, we develop a nice and clean API that we want to use instead, and then we create an abstraction that maps the clean API to the messy code we eventually want to remove.
Now we can start to swap out every instance where we use the old API and replace it step-by-step instead of one massive refactoring. As soon as we're done, we can remove the obsolete code and make the nice and clean abstraction the actual implementation. At that point, we can decide to either throw away the abstraction layer or keep it if it still makes sense.
References
Sponsors
Storyblok is a headless CMS with a Visual Editor. They’re currently working on their V2 release! You can join the beta crew if you want to be among the first to experience the new and improved editting experience.
Nuxt.js is a web framework for building modern apps & websites with Vue. They recently released nuxtlabs.com. I highly recommend you check that out!
Thanks for this "golden laser-pointer"! I'm a beginner with Vue, currently building on the Laravel stack and I'm sniffing all over the place for related info.
This one is going to bookmarks!
And from a brief browse here on your Substack, I see you cover not only Vue topics but other valuable topics too.
I'm not about to become a paid subscriber just yet, as I want to get a better feel for the stuff in general and then make a final selection or two on those teaching sources that make sense to me.
Definitely keeping an eye, both here and on the app, on your work, and might be back sooner rather than later for paid content.
Thanks for your efforts, Markus.