Boost Dev Productivity with Global HMR in Pinia for Quasar Apps
Boost Dev Productivity with Global HMR in Pinia for Quasar Apps

Globally Enable HMR for Pinia in Vue 3 + Quasar Without Repeating Code

Simplify Pinia HMR setup for Vue 3 + Quasar apps by globally enabling Hot Module Replacement to boost dev productivity.6 min


Pinia has quickly become the preferred state management tool among Vue 3 and Quasar developers, thanks to its simplicity and powerful features. It leverages the Vue Composition API seamlessly, offering a clean and organized way to manage application-wide state. While working with large-scale Quasar applications, constant code updates during development require Hot Module Replacement (HMR) to streamline the workflow. Typically, developers add explicit HMR code in each Pinia store. But this repetitive task quickly becomes tedious—prompting the question: can you globally enable HMR without repeating yourself?

Current Approach to HMR in Pinia Stores

If you’re currently developing Vue 3 + Quasar applications, chances are you’ve dealt with Pinia store files that contain individual HMR handlers. The common practice is to add code similar to the snippet below directly in every store file:


import { defineStore, acceptHMRUpdate } from "pinia";
import { useUserStore } from "./user-store";

export const useAuthStore = defineStore("authStore", () => {
  const isAuthenticated = ref(false);
  
  const login = () => {
    isAuthenticated.value = true;
  };

  return { isAuthenticated, login };
});

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useAuthStore, import.meta.hot));
}

Placing this HMR snippet at the bottom of every individual file is simple enough for small projects. But imagine scaling up to dozens or hundreds of store modules. Copying and pasting the same piece of code repeatedly across multiple files quickly becomes inefficient. Moreover, if changes are needed to the HMR setup later, it means touching every single store file, creating maintenance headaches.

Exploring Options for Global HMR Activation

An ideal solution would involve setting up global HMR support in your store directory, eliminating repetitive code in each file. One possibility is configuring global HMR handling directly in your store barrel file—the one typically named src/stores/index.ts.

Before you attempt this approach, though, it’s crucial to understand potential challenges. Pinia documentation mentions HMR explicitly in the context of individual stores, hinting it might be challenging to set up globally without explicit references. Additionally, ensuring Vite and Quasar compatibility adds complexity. The solution needs to handle dynamic imports seamlessly because store modules could vary in structure and size.

Proposed Solution for Enabling Global HMR

Luckily, it’s achievable with syntactic sugar and smart configurations, making your project more maintainable and your developer workflow smoother.

Here’s a straightforward, step-by-step guide on setting up global HMR for Pinia in your Vue 3 + Quasar projects:

1. Structuring Your Stores Index File

First, make sure you have an organized and consistent store structure. Typically, you’ll have a file like src/stores/index.ts to manage all your stores centrally. Your store index file should clearly export all your different Pinia stores, as shown here:


// src/stores/index.ts
import { createPinia } from "pinia";

const pinia = createPinia();

export default pinia;

2. Implement Global HMR Handling

Next, extend your global store entry to automatically integrate HMR without repeatedly editing every file. You can achieve this by dynamically importing all store modules using Vite’s built-in support for dynamic imports and modules:


import { createPinia, acceptHMRUpdate } from "pinia";

const pinia = createPinia();

if (import.meta.hot) {
  const modules = import.meta.glob("./*.ts", { eager: true });
  
  Object.entries(modules).forEach(([path, mod]) => {
    if (mod && mod.useStore && typeof mod.useStore === 'function') {
      import.meta.hot.accept(path, (newModule) => {
        if (!newModule) return;
        acceptHMRUpdate(newModule.useStore, import.meta.hot);
      });
    }
  });
}

export default pinia;

Here’s what this does:

  • Uses import.meta.glob to dynamically import every store matching the file pattern.
  • Loops through imported stores, checking for the useStore function export (typical of Pinia store files).
  • Automatically sets HMR handler for each store module within the global scope, removing the need for individual setups.

3. Adjusting Individual Store Exports for Global Handling

Each Pinia store should follow the same consistent naming convention. For example:


// src/stores/auth-store.ts
import { defineStore } from "pinia";

export const useStore = defineStore("authStore", () => {
  const isAuthenticated = ref(false);

  const login = () => {
    isAuthenticated.value = true;
  };

  return { isAuthenticated, login };
});

This standardized export (with a consistent useStore naming convention) ensures compatibility with the global dynamic import approach above.

Benefits of Enabling Global HMR in Pinia Stores

Integrating global HMR offers significant benefits that go beyond code simplicity:

  • Improved maintainability: Centralizes changes, so updates or fixes to the HMR setup only happen in a single file, not across many different files, reducing the risk of inconsistencies and errors.
  • Cleaner code: Eliminates redundant HMR snippets scattered across your stores, significantly improving your code readability and maintainability.
  • Enhanced developer productivity: Faster HMR setups streamline your development cycle, reducing wait times during coding sessions.

Considerations for Ongoing Maintenance

While the solution above is scalable and easy to manage, remember a few key aspects as your project evolves:

  • Consistency is key: Ensure every new store module follows your established convention to prevent import issues.
  • Watch for updates in Quasar, Vite, and Pinia: Keep an eye on release notes for any breaking changes regarding Vite HMR and Pinia integrations.
  • Troubleshooting guidance: If HMR stops working, double-check browser console errors and consult developer forums like Stack Overflow, or community discussions for similar issues.

It’s helpful to regularly test the HMR functionality after any major updates to your build system or core frameworks.

As you explore optimizing your workflow further, don’t forget to harness the power of TypeScript as well. You can read more about optimizing your JavaScript and TypeScript usage in Vue and Quasar apps at this JavaScript category page.

Enabling global HMR in Pinia makes a noticeable difference in your development workflow, freeing you from repetitive work and letting you focus more on building features. Creating centralized and globally maintained state management processes can have a profound impact on your team’s productivity.

How has HMR optimization impacted your Pinia + Quasar workflow recently? Share your experiences or examples in the comments—we’d love to hear how you streamlined your state management approach!


Like it? Share with your friends!

Shivateja Keerthi
Hey there! I'm Shivateja Keerthi, a full-stack developer who loves diving deep into code, fixing tricky bugs, and figuring out why things break. I mainly work with JavaScript and Python, and I enjoy sharing everything I learn - especially about debugging, troubleshooting errors, and making development smoother. If you've ever struggled with weird bugs or just want to get better at coding, you're in the right place. Through my blog, I share tips, solutions, and insights to help you code smarter and debug faster. Let’s make coding less frustrating and more fun! My LinkedIn Follow Me on X

0 Comments

Your email address will not be published. Required fields are marked *