Skip to content

Lifecycle Hooks

  • onBuildStart — Called before processing begins (or before each output is processed).
  • onBuildEnd — Called when processing finishes (or when each output completes).

Hooks are available at two levels:

  • GlobalBuildConfig.hooks — runs for the entire build.
  • Per-outputOutputConfig.hooks — runs for each output.
  1. Global onBuildStart — Before permutation resolution.
  2. Per-output onBuildStart — Before each output is processed.
  3. Per-output onBuildEnd — After each output finishes.
  4. Global onBuildEnd — After all outputs complete.
  • onBuildStart receives: { config: BuildConfig; resolver: string | ResolverDocument }
  • onBuildEnd receives: BuildResult

Both sync and async functions are supported.

await dispersa.build({
hooks: {
onBuildStart: ({ config }) => {
console.log(`Building ${config.outputs.length} output(s)...`)
},
onBuildEnd: (result) => {
if (result.success) {
console.log(`Done: ${result.outputs.length} file(s)`)
} else {
console.error(`Failed: ${result.errors?.length} error(s)`)
}
},
},
outputs: [
css({
name: 'css',
preset: 'bundle',
hooks: {
onBuildStart: () => console.log('[css] starting...'),
onBuildEnd: (result) => console.log(`[css] ${result.success ? 'done' : 'failed'}`),
},
}),
],
})
Use caseHookLevel
Build timingonBuildStart / onBuildEndGlobal
File size reportingonBuildEndPer-output
CI notifications (Slack, etc.)onBuildEndGlobal
Run Prettier on outputonBuildEndPer-output
Validation before buildonBuildStartGlobal
Per-output debuggingonBuildStart / onBuildEndPer-output

Example: running Prettier on generated CSS:

import { format } from 'prettier'
import { writeFile } from 'node:fs/promises'
css({
name: 'css',
file: 'tokens.css',
hooks: {
onBuildEnd: async (result) => {
if (result.success && result.outputs?.[0]?.content) {
const formatted = await format(result.outputs[0].content, { parser: 'css' })
await writeFile('dist/tokens.css', formatted)
}
},
},
})