A Vite plugin hook order that is Rollup’s, not Vite’s

A Vite plugin is a Rollup plugin with extra optional hooks, so the ordering rules and the hook names come from Rollup’s documentation rather than Vite’s.

export default function myPlugin() {
  return {
    name: 'my-plugin',
    enforce: 'pre',          // 'pre' | default | 'post' — Vite's
    apply: 'build',          // or 'serve' — also Vite's

    resolveId(source) {},    // Rollup
    load(id) {},             // Rollup
    transform(code, id) {},  // Rollup

    configResolved(config) {},   // Vite only
    transformIndexHtml(html) {}, // Vite only
  }
}

The enforce and apply fields are the Vite additions that control when a plugin runs relative to Vite’s own, and getting them wrong produces a plugin that appears to do nothing. Everything else is Rollup, which is why searching for a Vite plugin problem usually finds the answer in a Rollup issue.