Releases: elixir-volt/volt
v0.6.2
v0.6.1
Bug Fixes
- Fix plugin
content_typebeing ignored — when a plugin returned
{:ok, code, "application/javascript"}for a.vuefile, Pipeline
still ran Vue SFC compilation on the already-compiled JS - Fix virtual modules (
resolve→"virtual:...") failing with
:enoent— Collector now calls pluginloadbeforeFile.read - Fix duplicate label crash when multiple files share the same basename
(e.g.a/index.jsandb/index.js) — labels are disambiguated with
parent directory prefix and recursive_2suffix fallback - Thread plugin
content_typethrough Collector so import extraction
dispatches consistently with Pipeline
v0.6.0
Per-Module ESM Dev Server with HMR
The dev server now serves individual ESM modules instead of opaque compiled
files. Each .ts, .vue, .jsx file gets its own URL, and import specifiers
are rewritten so the browser resolves the full module graph natively:
- Relative imports (
./utils) →/assets/utils.ts - Bare imports (
vue) →/@vendor/vue.js(pre-bundled) - Alias imports (
@/utils) → resolved via tsconfig paths or config aliases
Each JS module is injected with an import.meta.hot preamble for granular HMR:
if (import.meta.hot) {
import.meta.hot.dispose(() => clearInterval(timer));
import.meta.hot.accept();
}On file change, the watcher walks the dependency graph upward to find the
nearest import.meta.hot.accept() boundary. Only that module is re-imported
via import("/@assets/Button.tsx?t=123") — no full page reload. Accept
callbacks receive the new module exports. Falls back to location.reload()
when no boundary is found.
TypeScript assets (HMR client, console forwarder, error overlay) are now
compiled to JS via OXC before serving to the browser.
Production Source Maps
Source maps are now fully usable in production builds:
sourcemap: true— write.mapfiles and append//# sourceMappingURL(default)sourcemap: :hidden— write.mapfiles without the URL comment (for Sentry, Datadog)sourcemap: false— no source maps- Chunked builds now generate source maps (previously discarded)
- CLI:
--sourcemap hidden
tsconfig.json Paths
Volt automatically reads compilerOptions.paths from tsconfig.json in the
project root and merges them into aliases. Explicit aliases take precedence.
Supports baseUrl for path resolution.
Manual Chunk Splitting
Control chunk boundaries via config:
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.
Bug Fixes
- Fix alias-imported Vue SFCs silently dropping bare npm imports from the bundle
Internal
- Reorganize internal modules into
Volt.JS.*,Volt.CSS.*,Volt.Dev.*namespaces - Add Playwright browser integration tests (
mix test --include integration)
v0.5.0
Tailwind Plugin & Config Support
Volt now resolves and bundles any Tailwind plugin or config on the fly — no vendored JS needed.
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "./my-plugin.js";
@config "./tailwind.config.js";Local plugins with require() dependency graphs are prebundled automatically via OXC.
Bundling Fix
Fixed a bug where bundling multiple npm packages (e.g. vue + @vue-flow/core) could produce SyntaxError: Identifier has already been declared due to scope collisions in the output.
Other Fixes
Preload.tags/2now correctly generates modulepreload tags from manifests- File watcher detects create/close events, not just modifications
- ETS cache tables are properly supervised (no more startup race)
Dependency Upgrades
oxc ~> 0.7.0,quickbeam ~> 0.10.0,npm ~> 0.5.3
Release 0.4.3
Bump quickbeam to 0.8.1, remove stale package.json and vendoring tasks.
Release 0.4.2
- Fix fresh installs for Tailwind support by removing the generated
priv/tailwind.jsworkflow - Assemble the Tailwind runtime on first use from the
tailwindcsspackage in thenpm_excache - Bump QuickBEAM to 0.8.0 and npm_ex to 0.5.1
Release 0.4.1
TypeScript Assets
Browser JavaScript (HMR client, error overlay, dev console forwarder) moved from inline Elixir heredocs to separate TypeScript files in priv/ts/.
Maintainer Tooling
mix volt.js.check— oxfmt format check and oxlint via npxmix volt.js.fmt— format TypeScript assets via npxmix volt.npm— install JS tooling deps via npm_exmix volt.vendor.tailwind— regeneratepriv/tailwind.jsfrom installed tailwindcss
Tailwind Vendoring
priv/tailwind.js is now generated from the tailwindcss npm package by mix volt.vendor.tailwind instead of being maintained by hand.
Build Improvements
- Structured manifest entries with
file,src,assets, andcssfields - Standalone CSS entries in the manifest
- Worker entry groundwork
- Hardened package resolution with
browser/import/default/requireand CJS support - Dev console forwarding from browser to terminal
v0.4.0
Highlights
- External globals —
external: ["vue"]generatesconst { ref, h } = Vue;in IIFE output instead of silently stripping imports - CSS
@importinlining — LightningCSS Bundler resolves imports recursively with@media/@supports/@layerwrapping - HTML entry points —
<script src="...">tags extracted via Floki import.meta.glob()— glob patterns expanded at build time via OXC AST- Module preload —
Volt.Preload.tags/2generates<link rel="modulepreload">from manifest - Gzip reporting — build output shows
128.4 KB (gzip: 38.6 KB)
Bug Fixes
- HMR: granular Vue SFC change detection (style-only updates) now works — cache lookup was using mtime 0
- Vendor URLs: scoped packages (
@vue/shared) no longer break on round-trip encoding - CSS Pipeline: errors no longer crash, properly returned as
{:error, reason} .envparsing: replaced hand-rolled parser with Dotenvy
Internal
- Tailwind GenServer lazily initializes QuickBEAM runtime on first call
- Deduplicated
content_hash,file_mtime,derive_global_name,extract_vue_imports - IIFE injection uses OXC AST instead of string splitting
- HTML parsing uses Floki instead of regex
- Dependencies: oxc ~> 0.5.2, vize ~> 0.8.0, floki ~> 0.38, dotenvy ~> 1.1
See CHANGELOG.md for full details.
v0.3.0
First feature release — code splitting, plugin system, CSS Modules, static assets, JSON imports, env variables, import aliases, external modules, centralized config, multi-entry builds.
See CHANGELOG.md for details.