JavaScript Usage
InferDI is authored in TypeScript, but JavaScript projects consume the built npm package through the package exports map.
| Example | Shows |
|---|---|
node-esm.mjs | Node ESM import with // @ts-check and JSDoc constructor types |
node-commonjs.cjs | Node CommonJS require() through the package exports map |
browser-vite.js | Browser-oriented ESM for Vite or another 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()Repository file: 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
})Repository file: examples/javascript/node-commonjs.cjs
Browser with Vite
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()
}
}Repository file: examples/javascript/browser-vite.js
