3

My project is using Nuxt, and I would like to implement dynamic injection of my services. It means I just add a class to my specific folder, and the class will be automatically injected into the context.

For instance, these are my classes placed in nuxtApp/service:

// /service/foo.service.js
export class FooService {
  constructor (context) {
    this.context = context
  }
  
  functionFoo (param) {
    console.log(`FooService.functionFoo: ${param}`)
  }
}

// /service/bar.service.js
export class BarService {
  constructor (context) {
    this.context = context
  }
  
  functionBar (param) {
    console.log(`BarService.functionBar: ${param}`)
  }
}

And this is how my plugin currently looks like, but I would like to automate it:

// /plugins/service-loader.js
import { FooService } from '../service/foo.service'
import { BarService } from '../service/bar.service'

export default ({ app }, inject) => {
  const fooService = new FooService(app)
  inject('fooService', fooService)

  const barService = new BarService(app)
  inject('barService', barService)
}

Is it possible to create automatically loading of services placed in the /service folder, and then inject their instance into the context?

1 Answer 1

3

You could use a Nuxt module to provide plugins for ~/service/*.service.js. The module would scan the service/ directory, and call addPlugin() for each .service.js file:

// ~/modules/service-loader.js
import path from 'path'
import glob from 'glob'

export default function serviceLoader() {
  glob(path.resolve(__dirname, '../service/**/*.service.js'), { follow: true }, (err, files) => {
    if (err) throw err

    for (const file of files) {
      const exportedMembers = Object.keys(require(file))
      if (!exportedMembers.length) return

      const className = exportedMembers[0]
      this.addPlugin({
        src: path.resolve(__dirname, './service-template.js'),
        fileName: path.basename(file),
        options: {
          className,
          propName: className.slice(0,1).toLowerCase() + className.substring(1),
          moduleName: file,
        }
      })
    }
  })
}
// ~/modules/service-template.js
import { <%= options.className %> } from '<%= options.moduleName %>'

export default ({ app }, inject) => {
  const <%= options.propName %> = new <%= options.className %> (app)
  inject('<%= options.propName %>', <%= options.propName %>)
}

Install this module under the modules array in your Nuxt config:

// nuxt.config.js
export default {
  modules: [
    '~/modules/service-loader'
  ],
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.