Skip to content

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.


Install vite-plugin-avenx along with vite as development dependencies in your project:

Terminal window
npm install -D vite-plugin-avenx vite

Register avenxPlugin inside the plugins array of your Vite configuration file:

vite.config.js
import { defineConfig } from 'vite';
import avenxPlugin from 'vite-plugin-avenx';
export default defineConfig({
plugins: [
avenxPlugin({
debug: false,
}),
],
});

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>;
}
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.

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

The compiler (createCompiler) automatically derives the JavaScript class name from the source filename:

  1. Strips the .component.js or .page.js extension from path.basename(filePath).
  2. Splits the remaining string by hyphens (-) or underscores (_).
  3. Capitalizes each segment into PascalCase format.

Examples:

  • src/components/user-card.component.jsUserCard
  • src/pages/shopping_cart.page.jsShoppingCart
  • src/components/nav.component.jsNav

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;
}

After ComponentParser finishes parsing the HTML template, state bindings, and component logic, the compiler wraps the output in standard ES module syntax:

import { AvenxComponent } from 'avenx-core/core';
// [Compiled Component Logic]
export default UserCard;
import { AvenxPage } from 'avenx-core/runtime';
// [Compiled Page Logic]
export default ShoppingCart;

vite-plugin-avenx integrates with Vite’s HMR system via the handleHotUpdate(ctx) hook.

hmr.js
export function handleAvenxHotUpdate(ctx) {
const { file, server } = ctx;
if (!isAvenxFile(file)) {
return;
}
console.log('[HMR]', file);
server.ws.send({
type: 'full-reload',
});
return [];
}
  1. File Change Detection: When a .component.js, .page.js, .component.css, or .page.css file is updated, Vite triggers handleHotUpdate.
  2. WebSocket Notification: The plugin intercepts the update and sends a { type: 'full-reload' } WebSocket signal to the client browser.
  3. 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

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.

During template compilation (compileComponent and compilePage), vite-plugin-avenx constructs a Source Map v3 compliant mapping object:

  • Constructor & State Initialization: Maps constructor() and super() 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.

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.js or .page.js source 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.

You can explicitly configure sourcemap generation in your vite.config.js:

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
},
});

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,
},
});

  • Symptom: Files are served as raw JavaScript or produce unexpected module export errors.
  • Cause: The file name does not end with .component.js or .page.js.
  • Fix: Ensure all component files strictly use .component.js and page files strictly use .page.js. Generic .js files are ignored by the plugin’s enforce: 'pre' hooks.
  • 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-avenx derives class names by stripping extensions and splitting on - and _. Ensure filenames match expected conventions (e.g. nav-bar.component.js generates NavBar).
  • Symptom: SyntaxError: Identifier 'default' has already been declared.
  • Cause: Manually adding export default inside a .component.js or .page.js file.
  • Fix: Do not write explicit export default statements inside component or page templates. The plugin automatically appends export default ClassName during module wrapping.