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.