DEV Community

Cover image for How to Manage Plugin Dependencies in Nuxt 3
J-Sandaruwan
J-Sandaruwan

Posted on

How to Manage Plugin Dependencies in Nuxt 3

Understanding the Issue

In a Nuxt 3 application, plugins are used to extend the application by injecting functionalities such as services, utilities, or initializing features during app startup.

When you have:

  • Plugin for Task A: A plugin that performs a certain task asynchronously (e.g., fetching data, setting up configuration).
  • Plugin for Task B: Another plugin that needs Task A to be fully completed before it runs.

If there is no enforced order or dependency management between these two plugins, you face an issue:

  • Plugin B might execute before Task A is finished.
  • This can cause problems if Task B relies on some side effects, data, or setup done by Task A.

This happens because Nuxt by default loads plugins based on their order in the directory or filename, but it does not wait for async plugins to finish before loading the next unless explicitly told.


Why Order or Dependency Matters

When your plugins involve asynchronous initialization (like API calls, authentication, or complex config loading), task order becomes critical. For example:

  • Task A might be an API token fetch.
  • Task B uses that API token for further calls or setups.

If Task B starts too early, it sees no token and fails.


How Nuxt 3 Handles Plugins

Nuxt 3 introduced features in the plugin system for better control:

  1. Plugins are executed in the order of discovery, which you can influence by file naming.
  2. Plugins can be asynchronous by returning or awaiting promises inside the setup function.
  3. Plugins can declare dependencies on other plugins using the dependsOn attribute.

Step-by-Step Explanation to Fix

1. Naming Plugins for Order

The simplest form of ordering is in the filesystem:

  • Name Plugin A file as 01-plugin-a.js
  • Name Plugin B file as 02-plugin-b.js

This ordering tells Nuxt to load Plugin A before Plugin B.

2. Use Async setup Hook

Let Plugin A's setup wait for async tasks to complete:

export default defineNuxtPlugin({
  name: 'plugin-a',
  async setup(nuxtApp) {
    // simulate async task
    await new Promise(resolve => setTimeout(resolve, 2000));
    console.log('Task A completed');
  },
});
Enter fullscreen mode Exit fullscreen mode

3. Declare Dependency with dependsOn

Tell Plugin B it depends on Plugin A like this:

export default defineNuxtPlugin({
  name: 'plugin-b',
  dependsOn: ['plugin-a'],
  async setup(nuxtApp) {
    console.log('Task B running after Task A');
  },
});
Enter fullscreen mode Exit fullscreen mode

Nuxt will guarantee that Plugin A finishes (including waiting for async setup to complete) before Plugin B runs. The dependsOn option is vital for explicit dependency management and protecting against loading surprises.


What Happens Under the Hood?

  • Nuxt collects all plugins and figures out their dependencies.
  • It sorts and runs them in dependency order.
  • For async plugins, it waits for the setup function's promise to resolve.
  • Only after Plugin A's setup is fully completed, Plugin B's setup starts.

Benefits of This Approach

  • Reliability: You won’t face race conditions or errors related to incomplete initialization.
  • Maintainability: Explicit dependencies are documented inside plugins themselves.
  • Scalability: Works well as the number of plugins grows and interdependencies increase.
  • Async Support: Fits well with modern asynchronous workflows such as API calls or dynamic config loading.

Real-World Use Cases

  • Authentication plugin that fetches and sets a user token.
  • Analytics plugin that needs the user session from authentication.
  • Feature flag plugin that depends on configuration setup by another plugin.
  • Localization setup plugin that relies on a backend service initialized in an earlier plugin.

Summary: How to Fix Your Issue in Vue 3 Nuxt 3

  1. Make sure Plugin A runs before Plugin B. You can do this by:
    • Naming plugin files in a sequence like 01- and 02-.
    • Using the dependsOn: ['plugin-a'] property in Plugin B.
  2. Make Plugin A's setup async and await any required asynchronous tasks.
  3. Nuxt will handle running Plugin B only after Plugin A is completed.
  4. This resolves dependency issues and ensures Task B runs with Task A's context fully ready.

Thank you,
Janith Sandaruwan.
linkedin

Top comments (0)