Skip to content

wgorzawski/nuxt-di

Repository files navigation

Nuxt DI

npm version npm downloads License Nuxt

A Nuxt 3 module that adds Inversion of Control (IoC) and Dependency Injection (DI) support using the Awilix library. It simplifies dependency management and helps structure code.

Features

  • Automatic Dependency Loading: Configure and load services dynamically.
  • Class Registration: Register services as classes, supporting constructor-based DI.
  • Composables Integration: Inject services directly into your components or composables.
  • Lightweight Decorators: Simplify dependency injection in classes.
  • Nuxt Native Support: Fully compatible with Nuxt's auto-import and plugin ecosystem.

Installation

Install the module to your Nuxt application with one command:

npx nuxi module add nuxt-di

and add it to your nuxt.config.ts file:

import { defineNuxtConfig } from 'nuxt/config';

export default defineNuxtConfig({
  modules: ['nuxt-di'],
  nuxtDi: {
    containerPath: '~/container' // Optionally add path to your container configuration
  }
});

Create the ~/container.ts file:

import { $MyService } from '~/symbol';
import MyService from '~/services/myService';
import UserService from '~/services/userService';

export default ({ registerClass }: any): void => {
  registerClass($MyService, MyService);
  registerDependency('userService', asClass(UserService).singleton());
};

That's it! You can now use Nuxt DI in your Nuxt app ✨

Usage

services/userService.ts

export default class UserService {
  public get userName(): string {
    return 'John';
  }

  public get userSurname(): string {
    return 'Doe';
  }
}

services/myService.ts

import type UserService from './userService';

export default class MyService {
  private readonly userService: UserService;

  constructor({ userService }: { userService: UserService }) {
    this.userService = userService;
  }

  public get user(): string {
    return `${this.userService.userName} ${this.userService.userSurname}`;
  }
}

app.vue

<template>
  <div class="home-page">
    <p>{{ user }}</p>
    <p>{{ userName }}</p>
  </div>
</template>

<script setup lang="ts">
  import { $MyService } from '~/symbol';
  import UserService from '~/services/userService';

  const userService = useContainer<UserService>('userService');
  const userName = userService.userName;

  const container = useContainer();
  const myService = container.resolve($MyService);
  const user = myService.user;
</script>

License

MIT