AlexOp Newsletter: Building Smarter with AI, GraphQL, and Vue

👋 Intro:
This week, I wrapped up Chip Huyen’s AI Engineering, a fantastic deep dive into building real-world AI systems with foundation models. It’s sparked a new obsession: learning everything I can about AI. I’ve also decided to start blogging about GraphQL + Vue, drawing from a year of hands-on experience at work.

📌 New Posts:

🔗 3 Links I Loved:

  • Distributed Tracing with OpenTelemetry - Part I (https://signoz.io/blog/opentelemetry-distributed-tracing-part-1/) – A clear introduction to OpenTelemetry and distributed tracing, perfect for understanding how to monitor complex systems effectively.

  • DeepWiki: AI-Powered GitHub Documentation (https://deepwiki.com/vuejs/core) – DeepWiki transforms GitHub repositories into interactive, AI-generated wikis, making it easier to explore and understand codebases.

  • Vue 3 Snapshot Testing Tutorial (https://www.youtube.com/watch?v=PVqMzrt9r-Q) – A helpful video demonstrating how to write better snapshot tests for Vue 3 components using a plugin that improves snapshot readability and maintenance.

One-Minute Tip:
Did you know you can save and reuse prompts in GitHub Copilot to supercharge your coding?

Here's how:
👉 Prompt Files (*.prompt.md) let you create reusable prompts directly in your project. Just enable "chat.promptFiles": true in VS Code settings and create a .github/prompts folder. Inside it, write Markdown files with your custom prompts!

Example — I built one for refactoring Vue components into inline composables:

# Inline Vue Composables Refactoring

Refactor the given Vue 3 `<script setup>` component to use **inline composables**, following Martin Fowler's Extract Function pattern.

## What is a Composable?
A composable is a function that leverages Vue's Composition API reactivity system. It must import and use at least one reactive feature from Vue (such as `ref`, `reactive`, `computed`, `watch`, etc.) to manage stateful logic.

## Instructions

1. **Identify related logic groups**  
   - State (`ref`, `reactive`, `computed`, etc.)  
   - Watchers (`watch`, `watchEffect`)  
   - Lifecycle hooks (`onMounted`, `onUnmounted`, etc.)
   - Async or sync functions (mutations, API calls)

2. **Extract each group into an inline composable**  
   - Declare a function inside the same `<script setup>` block named `useXyz()`, where `Xyz` clearly describes the concern (e.g. `useHiddenFolders`, `useFavoriteFolders`).  
   - Move related state, watchers, lifecycle hooks, and methods into that function.  
   - Return only the reactive variables and methods needed by the template.

3. **Update top‑level code**  
   - Replace the original state/watchers/functions with calls to the new inline composables:  
     ```js
     const { foo, toggleFoo } = useFooLogic()
     ```
   - Keep imports at the top; composable definitions below all top-level code.

4. **Maintain file structure and functionality**  
   - Keep the `<script setup>` wrapper intact.  
   - Preserve all imports, type annotations, and existing behavior.
   - Ensure returned refs/reactive objects maintain their reactivity.

5. **Example**

   **Before refactoring**  
   ```js
   <script setup>
   import { ref, watch } from 'vue'
   import { useQuery, mutate } from 'vue-apollo'
   import FOLDERS_FAVORITE from '@/graphql/folder/favoriteFolders.gql'
   import FOLDER_SET_FAVORITE from '@/graphql/folder/folderSetFavorite.gql'

   async function toggleFavorite(currentFolder) {
     await mutate({ mutation: FOLDER_SET_FAVORITE, variables: { path: currentFolder.path, favorite: !currentFolder.favorite } })
   }

   const showHidden = ref(localStorage.getItem('show-hidden') === 'true')
   watch(showHidden, v => {
     if (v) localStorage.setItem('show-hidden', 'true')
     else localStorage.removeItem('show-hidden')
   })

   const favoriteFolders = useQuery(FOLDERS_FAVORITE, [])
   </script>
   ```

   **After refactoring**  
   ```js
   <script setup>
   import { ref, watch } from 'vue'
   import { useQuery, mutate } from 'vue-apollo'
   import FOLDERS_FAVORITE from '@/graphql/folder/favoriteFolders.gql'
   import FOLDER_SET_FAVORITE from '@/graphql/folder/folderSetFavorite.gql'

   const { showHidden } = useHiddenFolders()
   const { favoriteFolders, toggleFavorite } = useFavoriteFolders()

   function useHiddenFolders() {
     const showHidden = ref(localStorage.getItem('show-hidden') === 'true')
     watch(showHidden, v => {
       if (v) localStorage.setItem('show-hidden', 'true')
       else localStorage.removeItem('show-hidden')
     }, { lazy: true })
     return { showHidden }
   }

   function useFavoriteFolders() {
     const favoriteFolders = useQuery(FOLDERS_FAVORITE, [])
     async function toggleFavorite(currentFolder) {
       await mutate({ mutation: FOLDER_SET_FAVORITE, variables: { path: currentFolder.path, favorite: !currentFolder.favorite } })
     }
     return { favoriteFolders, toggleFavorite }
   }
   </script>
   ```

You can then attach this prompt in Copilot Chat by clicking the 📎 icon and selecting your saved prompt.
Perfect for keeping your refactoring consistent and saving mental energy!

👉 Full guide if you want to set this up too: GitHub Docs – Adding Repository Custom Instructions for Copilot

P.S.
I'm just getting started! Next up, I’ll dive into how to make your Vue + GraphQL projects fully type-safe using GraphQL Codegen.

Best,

Alex