Dynamic imports are automatically split into separate chunks:
import { setup } from './core'
const admin = await import('./admin')Produces:
app-5e6f7a8b.js 42 KB (entry)
app-admin-c3d4e5f6.js 86 KB (async)
manifest.json 3 entriesShared modules between chunks are extracted into common chunks to avoid duplication. CSS imported by an async chunk is emitted beside that chunk, and CSS imported by shared chunks is tracked on the shared chunk.
When a dynamic import has dependencies that would otherwise create a loading waterfall, Volt rewrites it through a small preload helper. The helper preloads imported JavaScript chunks and chunk-local CSS before executing the dynamic import.
Disable with code_splitting: false in config or --no-code-splitting flag.
Manual Chunks
Control chunk boundaries explicitly:
config :volt,
chunks: %{
"vendor" => ["vue", "vue-router", "pinia"],
"ui" => ["assets/src/components"]
}Bare specifiers match package names in node_modules. Path patterns match by directory prefix. Manual chunks work alongside automatic dynamic-import splitting.
Manifest Metadata
Code-split builds write chunk relationships to manifest.json:
{
"app.js": {
"file": "app-a1b2c3d4.js",
"src": "app.js",
"isEntry": true,
"imports": ["common-11223344.js"],
"dynamicImports": ["app-admin-c3d4e5f6.js"],
"css": ["app-55667788.css"],
"assets": ["logo-99aabbcc.svg"]
}
}fileis the emitted JavaScript or CSS file.srcis present for source entry modules.importslists static chunk dependencies.dynamicImportslists async chunks loaded throughimport().csslists CSS files owned by the chunk.assetslists emitted non-code assets referenced by the chunk.
Use Volt.Preload.tags/2 from server-rendered layouts to generate preload tags for an entry and its static chunk imports. Runtime dynamic imports handle their own dependency preloads.