|
1 | 1 | # Changelog |
2 | 2 |
|
3 | | -## 0.3.0 |
| 3 | +## 0.4.0 |
4 | 4 |
|
5 | | -### Code Splitting |
| 5 | +### External Globals |
6 | 6 |
|
7 | | -Dynamic `import()` expressions are detected during the dependency walk and |
8 | | -split into separate async chunks. Shared modules between the entry chunk and |
9 | | -async chunks are extracted into a common chunk to avoid duplication. |
| 7 | +External imports now generate proper global variable access in the IIFE output |
| 8 | +instead of being silently stripped. Supports both auto-derived and explicit names: |
10 | 9 |
|
11 | | -```typescript |
12 | | -const admin = await import('./admin') // → app-admin-c3d4e5f6.js |
| 10 | +```elixir |
| 11 | +config :volt, external: ["vue"] |
| 12 | +# import { ref } from 'vue' → const { ref } = Vue; |
| 13 | + |
| 14 | +config :volt, external: %{"vue" => "MyVue"} |
| 15 | +# import { ref } from 'vue' → const { ref } = MyVue; |
13 | 16 | ``` |
14 | 17 |
|
15 | | -### External Modules |
| 18 | +### CSS `@import` Inlining |
16 | 19 |
|
17 | | -New `:external` option excludes specifiers from the bundle. Essential for |
18 | | -Phoenix apps where `phoenix`, `phoenix_html`, and `phoenix_live_view` are |
19 | | -provided by the framework: |
| 20 | +CSS files with `@import` rules are bundled via LightningCSS's Bundler. |
| 21 | +Imports are resolved recursively from disk with proper `@media`/`@supports`/`@layer` wrapping |
| 22 | +and `url()` rebasing. |
20 | 23 |
|
21 | | -```elixir |
22 | | -config :volt, external: ~w(phoenix phoenix_html phoenix_live_view) |
| 24 | +### HTML Entry Points |
| 25 | + |
| 26 | +Entry files can now be HTML — `<script src="...">` tags are extracted |
| 27 | +via Floki and used as JS entry points: |
| 28 | + |
| 29 | +```bash |
| 30 | +mix volt.build --entry index.html |
23 | 31 | ``` |
24 | 32 |
|
25 | | -### Centralized Configuration |
| 33 | +### `import.meta.glob()` |
26 | 34 |
|
27 | | -All config now lives under `config :volt` in your standard `config/*.exs` files, |
28 | | -following the same pattern as `phoenix`, `esbuild`, and `tailwind` hex packages: |
| 35 | +Glob patterns are expanded at build time via OXC AST: |
29 | 36 |
|
30 | | -```elixir |
31 | | -config :volt, |
32 | | - entry: "assets/js/app.ts", |
33 | | - target: :es2020, |
34 | | - external: ~w(phoenix phoenix_html phoenix_live_view), |
35 | | - aliases: %{"@" => "assets/src"}, |
36 | | - tailwind: [css: "assets/css/app.css", sources: [...]] |
| 37 | +```typescript |
| 38 | +const pages = import.meta.glob('./pages/*.ts') |
| 39 | +// → { "./pages/home.ts": () => import("./pages/home.ts"), ... } |
| 40 | + |
| 41 | +const eager = import.meta.glob('./pages/*.ts', { eager: true }) |
| 42 | +// → static imports with namespace bindings |
37 | 43 | ``` |
38 | 44 |
|
39 | | -Mix tasks and the DevServer plug read from config automatically. |
40 | | -CLI flags override for one-off use. |
| 45 | +### Module Preload |
41 | 46 |
|
42 | | -### Plugin System |
| 47 | +New `Volt.Preload.tags/2` generates `<link rel="modulepreload">` tags |
| 48 | +from the build manifest for production chunk preloading. |
43 | 49 |
|
44 | | -New `Volt.Plugin` behaviour with four optional hooks: |
45 | | -- `resolve/2` — remap import specifiers |
46 | | -- `load/1` — provide virtual module content |
47 | | -- `transform/2` — modify compiled output |
48 | | -- `render_chunk/2` — modify final output chunks |
| 50 | +### Build Size Reporting |
49 | 51 |
|
50 | | -### CSS Modules |
| 52 | +Build output now shows gzip sizes: |
51 | 53 |
|
52 | | -`.module.css` files are scoped using LightningCSS (via Vize 0.7.0). |
53 | | -Class names, IDs, keyframes, and custom identifiers are properly scoped |
54 | | -through a real CSS parser — no regex. |
| 54 | +``` |
| 55 | +app.js 128.4 KB (gzip: 38.2 KB) |
| 56 | +``` |
55 | 57 |
|
56 | | -### Static Asset Handling |
| 58 | +### Bug Fixes |
| 59 | + |
| 60 | +- **HMR**: Watcher cache lookup used mtime 0, so granular Vue SFC |
| 61 | + change detection (style-only updates) never worked. Fixed. |
| 62 | +- **Vendor URLs**: Scoped packages (`@vue/shared`) had lossy URL encoding |
| 63 | + that broke round-trips. Now uses reversible encoding. |
| 64 | +- **CSS errors**: Pipeline `compile_css` had no error clause and would |
| 65 | + crash on invalid CSS instead of returning an error. |
| 66 | +- **`.env` parser**: Replaced hand-rolled parser with Dotenvy for correct |
| 67 | + handling of multiline values, variable expansion, and escaping. |
| 68 | +- **IIFE injection**: External globals preamble injection now uses OXC AST |
| 69 | + to find the function body offset instead of fragile string splitting. |
| 70 | +- **Chunk URLs**: Dynamic import rewriting matches by path suffix instead of |
| 71 | + basename to avoid collisions between same-named files in different directories. |
| 72 | + |
| 73 | +### Internal Improvements |
| 74 | + |
| 75 | +- Tailwind GenServer lazily initializes QuickBEAM runtime on first call |
| 76 | + instead of on application start |
| 77 | +- Deduplicated `content_hash`, `file_mtime`, `derive_global_name`, |
| 78 | + `extract_vue_imports` across modules |
| 79 | +- Vendor cache dir respects `MIX_BUILD_PATH` |
| 80 | +- Tailwind bundle path uses `Application.app_dir` instead of compile-time |
| 81 | + `:code.priv_dir` |
| 82 | +- HTML parsing uses Floki instead of regex |
| 83 | +- Dependencies: oxc ~> 0.5.2, vize ~> 0.8.0, floki ~> 0.38, dotenvy ~> 1.1 |
57 | 84 |
|
58 | | -Images, fonts, SVGs, and other non-code files are handled automatically. |
59 | | -Small files (< 4KB) are inlined as base64 data URIs. Larger files are |
60 | | -served directly in dev and copied with content-hashed filenames in prod. |
| 85 | +## 0.3.0 |
61 | 86 |
|
62 | | -### JSON Imports |
| 87 | +### Code Splitting |
63 | 88 |
|
64 | | -`import data from './data.json'` compiles to `export default {...}`. |
| 89 | +Dynamic `import()` expressions are detected during the dependency walk and |
| 90 | +split into separate async chunks. Shared modules between the entry chunk and |
| 91 | +async chunks are extracted into a common chunk to avoid duplication. |
65 | 92 |
|
66 | | -### Environment Variables |
| 93 | +### External Modules |
67 | 94 |
|
68 | | -`.env` files are loaded and variables prefixed with `VOLT_` are available |
69 | | -as `import.meta.env.VOLT_*` in source code. Built-in `MODE`, `DEV`, and |
70 | | -`PROD` variables are always available. |
| 95 | +New `:external` option excludes specifiers from the bundle. |
| 96 | + |
| 97 | +### Centralized Configuration |
71 | 98 |
|
72 | | -### Import Aliases |
| 99 | +All config now lives under `config :volt` in your standard `config/*.exs` files: |
73 | 100 |
|
74 | 101 | ```elixir |
75 | | -config :volt, aliases: %{"@" => "assets/src"} |
| 102 | +config :volt, |
| 103 | + entry: "assets/js/app.ts", |
| 104 | + target: :es2020, |
| 105 | + external: ~w(phoenix phoenix_html phoenix_live_view), |
| 106 | + aliases: %{"@" => "assets/src"}, |
| 107 | + tailwind: [css: "assets/css/app.css", sources: [...]] |
76 | 108 | ``` |
77 | 109 |
|
78 | | -`import { Button } from '@/components/Button'` resolves to the configured path. |
| 110 | +### Plugin System |
79 | 111 |
|
80 | | -### Multiple Entry Points |
| 112 | +`Volt.Plugin` behaviour with resolve, load, transform, render_chunk hooks. |
81 | 113 |
|
82 | | -`--entry` flag is now repeatable for multi-page apps. Each entry produces |
83 | | -its own bundle and manifest entries. |
| 114 | +### CSS Modules |
84 | 115 |
|
85 | | -### Builder Refactor |
| 116 | +`.module.css` scoped via LightningCSS. No regex. |
86 | 117 |
|
87 | | -`Volt.Builder` split into focused submodules: |
88 | | -- `Volt.Builder.Resolver` — specifier resolution chain |
89 | | -- `Volt.Builder.Collector` — dependency graph walk with import type detection |
90 | | -- `Volt.Builder.Output` — chunk bundling, file writing, manifest |
91 | | -- `Volt.ChunkGraph` — chunk assignment from module dependency map |
| 118 | +### Static Assets, JSON Imports, Env Variables, Import Aliases |
92 | 119 |
|
93 | | -### Other Changes |
| 120 | +See README for full details. |
| 121 | + |
| 122 | +### Builder Refactor |
94 | 123 |
|
95 | | -- Config values use atoms (`:es2020`, `:production`) instead of strings |
96 | | -- DevServer serves static assets with correct MIME types |
97 | | -- `.json` recognized as compilable extension in DevServer and Builder |
98 | | -- Vize upgraded to 0.7.0 for CSS Modules support |
| 124 | +Split into `Volt.Builder.Resolver`, `Volt.Builder.Collector`, |
| 125 | +`Volt.Builder.Output`, and `Volt.ChunkGraph`. |
99 | 126 |
|
100 | 127 | ## 0.2.0 |
101 | 128 |
|
|
0 commit comments