Vite Plugin (vite-plugin-avenx)
The vite-plugin-avenx package brings native Vite integration to Avenx-JS projects. It executes during pre-transformation hooks (enforce: 'pre'), parses .component.js and .page.js files, processes companion CSS stylesheets, and triggers automatic reloads via Vite’s Hot Module Replacement (HMR) architecture.
Installation & Plugin Configuration
Section titled “Installation & Plugin Configuration”Package Installation
Section titled “Package Installation”Install vite-plugin-avenx along with vite as development dependencies in your project:
npm install -D vite-plugin-avenx viteBasic vite.config.js Setup
Section titled “Basic vite.config.js Setup”Register avenxPlugin inside the plugins array of your Vite configuration file:
import { defineConfig } from 'vite';import avenxPlugin from 'vite-plugin-avenx';
export default defineConfig({ plugins: [ avenxPlugin({ debug: false, }), ],});Plugin Options
Section titled “Plugin Options”The avenxPlugin(options) factory function accepts an optional configuration object:
interface AvenxPluginOptions { /** * Enables detailed debug logging in the Vite dev server console. * @default false */ debug?: boolean;
/** * Controls Source Map v3 generation for .component.js and .page.js templates during build & transformation passes. * @default true in dev */ sourcemap?: boolean;
/** * Configuration options passed directly to StyleProcessor. * @default {} */ style?: Record<string, any>;}Options Breakdown
Section titled “Options Breakdown”| Option | Type | Default | Description |
|---|---|---|---|
debug |
boolean |
false |
When enabled, logs file resolution, stylesheet loading, compilation phases (Compile Component, Compile Page), and HMR events to stdout ([vite-plugin-avenx] ...). |
sourcemap |
boolean |
true in dev |
Controls Source Map v3 generation for .component.js and .page.js templates during build & transformation passes. |
style |
object |
{} |
Options passed directly to internal StyleProcessor for CSS scoping, preprocessor handlers, or style transformations. |
SFC & Page Compilation Lifecycle
Section titled “SFC & Page Compilation Lifecycle”vite-plugin-avenx intercepts source files in Vite’s transform and load hooks using pre-defined file extensions.
Source Files (.component.js / .page.js) │ ▼ resolveId() ──► Check file naming conventions │ ▼ load() ──► Load & strip <@css> tags from .component.css / .page.css │ ▼ transform() ──► ComponentParser & StyleProcessor compilation │ ▼ wrapper ──► Wrap ES Module with default export (wrapComponent / wrapPage)1. File Identification & Naming Conventions
Section titled “1. File Identification & Naming Conventions”The plugin inspects file suffixes using the following strict extensions:
- Components:
.component.js - Pages:
.page.js - Component Styles:
.component.css - Page Styles:
.page.css
2. Automatic Class Name Derivation
Section titled “2. Automatic Class Name Derivation”The compiler (createCompiler) automatically derives the JavaScript class name from the source filename:
- Strips the
.component.jsor.page.jsextension frompath.basename(filePath). - Splits the remaining string by hyphens (
-) or underscores (_). - Capitalizes each segment into PascalCase format.
Examples:
src/components/user-card.component.js➔UserCardsrc/pages/shopping_cart.page.js➔ShoppingCartsrc/components/nav.component.js➔Nav
3. Stylesheet Preprocessing (loadStyle)
Section titled “3. Stylesheet Preprocessing (loadStyle)”When Vite imports or resolves a .component.css or .page.css file, loadStyle(filePath) reads the file and strips <@css> and </@css> block markers if present:
// Input stylesheet (.component.css)<@css>.user-card { display: flex; padding: 1rem;}</@css>
// Processed output loaded into module pipeline.user-card { display: flex; padding: 1rem;}4. ES Module Wrapping (wrapper.js)
Section titled “4. ES Module Wrapping (wrapper.js)”After ComponentParser finishes parsing the HTML template, state bindings, and component logic, the compiler wraps the output in standard ES module syntax:
Component Wrapping (wrapComponent):
Section titled “Component Wrapping (wrapComponent):”import { AvenxComponent } from 'avenx-core/core';
// [Compiled Component Logic]
export default UserCard;Page Wrapping (wrapPage):
Section titled “Page Wrapping (wrapPage):”import { AvenxPage } from 'avenx-core/runtime';
// [Compiled Page Logic]
export default ShoppingCart;Hot Module Replacement (HMR) Architecture
Section titled “Hot Module Replacement (HMR) Architecture”vite-plugin-avenx integrates with Vite’s HMR system via the handleHotUpdate(ctx) hook.
export function handleAvenxHotUpdate(ctx) { const { file, server } = ctx;
if (!isAvenxFile(file)) { return; }
console.log('[HMR]', file);
server.ws.send({ type: 'full-reload', });
return [];}How HMR Works
Section titled “How HMR Works”- File Change Detection: When a
.component.js,.page.js,.component.css, or.page.cssfile is updated, Vite triggershandleHotUpdate. - WebSocket Notification: The plugin intercepts the update and sends a
{ type: 'full-reload' }WebSocket signal to the client browser. - Empty Module Array: Returning
[]instructs Vite to bypass standard module invalidation for that file, preventing duplicate re-execution during full reload.
Vite Dev Server vs. Standalone avenx dev CLI
Section titled “Vite Dev Server vs. Standalone avenx dev CLI”| Feature | vite-plugin-avenx (Vite) |
avenx dev (CLI Dashboard) |
|---|---|---|
| Development Server | Vite Connect dev server | Native Node.js CLI server & dashboard |
| Hot Reloading | Vite WebSocket full reload (server.ws) |
Custom SSE / polling reload server |
| Module Bundling | ESbuild pre-bundling & Rollup production builds | Avenx CLI compiler output |
| Plugin Ecosystem | Full access to Vite plugins (PostCSS, Tailwind, PWA, etc.) | Zero-config standalone environment |
Template Source Maps & DevTools Debugging
Section titled “Template Source Maps & DevTools Debugging”vite-plugin-avenx includes native Source Map v3 generation for .component.js and .page.js files. During Vite transformation passes, the plugin constructs VLQ-encoded source maps mapping compiled JavaScript blocks (constructor initialization, action methods, computed property getters, resources, and rendered HTML templates) back to exact line numbers in original template files.
How Source Mapping Operates
Section titled “How Source Mapping Operates”During template compilation (compileComponent and compilePage), vite-plugin-avenx constructs a Source Map v3 compliant mapping object:
- Constructor & State Initialization: Maps
constructor()andsuper()state bindings back to original template<state>block lines. - Action Methods: Maps compiled action handlers (
<action name="...">) to their original template source line indices. - Computed Properties: Maps computed getters (
<computed name="...">) to their original source definitions. - Resource Management: Links resource hooks (
<resource name="...">) directly back to original template lines. - Template & Expression Interpolations: Maps transformed HTML template strings and dynamic string interpolations back to original template lines.
DevTools Integration
Section titled “DevTools Integration”Browser developer tools (Chrome DevTools, Firefox Developer Edition, Safari Web Inspector) leverage these VLQ-encoded source maps to map executed runtime ES modules back to your original source code:
- Line-by-Line Breakpoint Debugging: Place breakpoints directly inside original
.component.jsor.page.jssource files within browser DevTools. - Precise Stack Traces: Console errors and warnings display exact line numbers referencing original template source files rather than compiled bundle output.
- Scope & State Inspection: Inspect local variables, reactive component state, actions, and computed properties in their original template scope.
Configuration Example
Section titled “Configuration Example”You can explicitly configure sourcemap generation in your vite.config.js:
import { defineConfig } from 'vite';import avenxPlugin from 'vite-plugin-avenx';
export default defineConfig({ plugins: [ avenxPlugin({ debug: process.env.NODE_ENV === 'development', sourcemap: true, // Enable template line mapping for browser DevTools style: { scoped: true, }, }), ], build: { sourcemap: true, // Also generate JS bundle source maps },});Full vite.config.js Boilerplate
Section titled “Full vite.config.js Boilerplate”Here is a complete, production-ready vite.config.js example for building single-page or multi-page Avenx applications:
import { defineConfig } from 'vite';import avenxPlugin from 'vite-plugin-avenx';import path from 'node:path';
export default defineConfig({ plugins: [ avenxPlugin({ debug: process.env.NODE_ENV === 'development', sourcemap: true, style: { scoped: true, }, }), ], resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, server: { port: 3000, open: true, }, build: { target: 'esnext', outDir: 'dist', sourcemap: true, },});Troubleshooting Guide
Section titled “Troubleshooting Guide”1. Component or Page Is Not Compiling
Section titled “1. Component or Page Is Not Compiling”- Symptom: Files are served as raw JavaScript or produce unexpected module export errors.
- Cause: The file name does not end with
.component.jsor.page.js. - Fix: Ensure all component files strictly use
.component.jsand page files strictly use.page.js. Generic.jsfiles are ignored by the plugin’senforce: 'pre'hooks.
2. Class Name Derivation Mismatches
Section titled “2. Class Name Derivation Mismatches”- Symptom: Import statements or template references fail to find the exported component class.
- Cause: Filenames with non-alphanumeric characters or non-standard naming.
- Fix:
vite-plugin-avenxderives class names by stripping extensions and splitting on-and_. Ensure filenames match expected conventions (e.g.nav-bar.component.jsgeneratesNavBar).
3. Duplicate export default Syntax Error
Section titled “3. Duplicate export default Syntax Error”- Symptom:
SyntaxError: Identifier 'default' has already been declared. - Cause: Manually adding
export defaultinside a.component.jsor.page.jsfile. - Fix: Do not write explicit
export defaultstatements inside component or page templates. The plugin automatically appendsexport default ClassNameduring module wrapping.