Vite 8
amamoMdx gives one Vite plugin instance one lazily created compiler. Vite owns module transforms and
filesystem events; the compiler owns validated records, manifests, and generated collection files.
Configure the plugin
// vite.config.ts
import { amamoMdx } from '@amamo/mdx/vite'
import { defineConfig } from 'vite'
import amamo from './amamo.config.mjs'
export default defineConfig({
plugins: [amamoMdx(amamo)],
})The plugin is enforce: 'pre' and sharedDuringBuild: true. When a Vite multi-environment build is
configured to reuse shared plugins, client and SSR environments therefore use the same plugin
compiler instead of compiling the content set independently.
Import a document
import Post, { frontmatter } from './content/posts/hello.mdx'
export function Page() {
return (
<article>
<h1>{frontmatter.title}</h1>
<Post />
</article>
)
}For a recognized collection file, the transform hook ignores the incoming source string and asks
the compiler for the current JavaScript module. Frontmatter has already been validated, Markdown
media has been rewritten, and enabled Shiki output has been injected before Vite receives the code.
Lifecycle
| Vite hook or event | Compiler action |
|---|---|
buildStart | Run one complete build(). |
transform | Run transform(id) for recognized collection files. |
dev server add / change | Transform the path and refresh generated outputs. |
dev server unlink | Remove the known record and refresh generated outputs. |
dev HTTP server close | Detach watcher handlers and dispose the compiler. |
The first startup call is shared, so repeated build hooks do not start duplicate full builds. Compiler operations are serialized after that.
Development updates
When add, change, or unlink changes at least one generated output, the plugin invalidates
collections.mjs if it is in Vite's module graph and sends a full reload. There is no document-level
HMR boundary yet.
A watcher compilation failure is sent to Vite's logger and error overlay. Successful record warnings
such as AMAMO_MEDIA_MISSING remain in record.diagnostics; the plugin does not print them.
Generated collections
Application code may import the generated registry:
import { collections } from './.amamo-mdx/collections.mjs'
const published = collections.posts.filter((document) => !document.frontmatter.draft)Each registry item has metadata plus load: () => import(originalMdxPath). Vite processes that lazy
import through the same plugin. The plugin does not read index.json; that private index exists for
the Next loader.
Production builds
vite build runs the same full startup build and per-import transforms. Outputs whose bytes are
unchanged keep their modification times, which lets downstream tools avoid work.
Set cache: false only when repeated native/Shiki work is acceptable. Vite can transform without
persistent records, unlike the Next adapter.
Current limits
- Generated-output changes trigger a full reload.
- The plugin does not print
IBuildResult; call the direct Compiler API when a report is required. - Every plugin invocation owns separate compiler state. Register the plugin once for one content config.