Skip to content

Uso con JavaScript

InferDI está escrito en TypeScript, pero los proyectos de JavaScript consumen el paquete npm compilado a través del mapa de exports del paquete.

EjemploMuestra
node-esm.mjsImportación ESM en Node con // @ts-check y tipos de constructor mediante JSDoc
node-commonjs.cjsrequire() de CommonJS en Node a través del mapa de exports del paquete
browser-vite.jsESM orientado al navegador para Vite u otro bundler

Node ESM

js
// @ts-check

import { Container } from '@inferdi/inferdi'

class Logger {
  /**
   * @param {string} message
   */
  log(message) {
    console.log(`[LOG] ${message}`)
  }
}

class UserService {
  /**
   * @param {Logger} logger
   * @param {string} apiToken
   */
  constructor(logger, apiToken) {
    this.logger = logger
    this.apiToken = apiToken
  }

  /**
   * @param {string} id
   */
  find(id) {
    this.logger.log(`Finding user ${id} with token ${this.apiToken}`)
    return { id, name: 'Alice' }
  }
}

const container = new Container()
  .registerValue('token', 'secret-123')
  .registerClass('logger', Logger, [])
  .registerClass('userService', UserService, ['logger', 'token'])

// Uncomment in an editor with JavaScript type checking enabled:
// new Container()
//   .registerValue('token', 'secret-123')
//   .registerClass('logger', Logger, [])
//   .registerClass('userService', UserService, ['token', 'logger'])

console.log(container.get('userService').find('42'))

// If your runtime/toolchain supports Explicit Resource Management syntax,
// Container also supports: await using container = new Container()
await container.dispose()

Archivo del repositorio: examples/javascript/node-esm.mjs

Node CommonJS

js
// @ts-check

const { Container } = require('@inferdi/inferdi')

class Logger {
  /**
   * @param {string} message
   */
  log(message) {
    console.log(`[LOG] ${message}`)
  }
}

class UserService {
  /**
   * @param {Logger} logger
   * @param {string} apiToken
   */
  constructor(logger, apiToken) {
    this.logger = logger
    this.apiToken = apiToken
  }

  /**
   * @param {string} id
   */
  find(id) {
    this.logger.log(`Finding user ${id} with token ${this.apiToken}`)
    return { id, name: 'Alice' }
  }
}

async function main() {
  const container = new Container()
    .registerValue('token', 'secret-123')
    .registerClass('logger', Logger, [])
    .registerClass('userService', UserService, ['logger', 'token'])

  // Uncomment in an editor with JavaScript type checking enabled:
  // new Container()
  //   .registerValue('token', 'secret-123')
  //   .registerClass('logger', Logger, [])
  //   .registerClass('userService', UserService, ['token', 'logger'])

  console.log(container.get('userService').find('42'))

  // If your runtime/toolchain supports Explicit Resource Management syntax,
  // Container also supports: await using container = new Container()
  await container.dispose()
}

main().catch((error) => {
  console.error(error)
  throw error
})

Archivo del repositorio: examples/javascript/node-commonjs.cjs

js
// @ts-check

import { Container } from '@inferdi/inferdi'

class PageContext {
  constructor() {
    this.pageName = ''
  }
}

class ApiClient {
  async listProjects() {
    return [{ id: 'project_1', name: 'Docs' }]
  }
}

class ProjectsViewModel {
  /**
   * @param {PageContext} page
   * @param {ApiClient} api
   */
  constructor(page, api) {
    this.page = page
    this.api = api
  }

  async load() {
    return {
      page: this.page.pageName,
      projects: await this.api.listProjects(),
    }
  }
}

const root = new Container()
  .registerClass('page', PageContext, [], 'scoped')
  .registerClass('api', ApiClient, [])
  .registerClass('projectsVm', ProjectsViewModel, ['page', 'api'], 'scoped')

// Uncomment in an editor with JavaScript type checking enabled:
// new Container()
//   .registerClass('page', PageContext, [], 'scoped')
//   .registerClass('api', ApiClient, [])
//   .registerClass('projectsVm', ProjectsViewModel, ['api', 'page'], 'scoped')

export function createProjectsPageScope() {
  const scope = root.createScope()

  try {
    scope.get('page').pageName = 'projects'
    return scope
  } catch (error) {
    scope.dispose().catch(console.error)
    throw error
  }
}

/**
 * @param {HTMLElement} element
 */
export async function renderProjectsList(element) {
  const scope = createProjectsPageScope()

  try {
    const vm = scope.get('projectsVm')
    const data = await vm.load()

    element.textContent = `${data.page}: ${data.projects.map((project) => project.name).join(', ')}`
  } finally {
    await scope.dispose()
  }
}

Archivo del repositorio: examples/javascript/browser-vite.js