Rettangoli FE Docs
CLI

@rettangoli/fe includes CLI commands for building, developing, validating, and scaffolding components. All commands are run through the rtgl CLI.

Commands

Command Description
rtgl fe build Build component bundles
rtgl fe watch Start dev server with file watching
rtgl fe scaffold --category <folder> --component-name <name> Generate a new component from a template
rtgl fe check Validate components against contracts
rtgl fe examples Generate example specs for visual testing

rtgl fe build

Bundles all components found in the configured directories into a single output file.

rtgl fe build

Uses the outfile path from rettangoli.config.yaml:

fe:
  dirs:
    - "./src/components"
  outfile: "./dist/bundle.js"

The build uses Vite 8 (vite.build) with Rolldown and Oxc for production bundling and minification.

Source maps are off by default. --sourcemap writes a .map next to each emitted file and links it with a sourceMappingURL comment. --sourcemap hidden writes the same maps without the comment, so a shipped bundle never points at them; keep those maps privately to symbolicate production errors. Maps embed the original source code, so publish them only if that source may be public.

rtgl fe build --sourcemap hidden

rtgl fe watch

Starts a development server that watches for file changes and applies updates automatically.

rtgl fe watch

Uses Vite (vite.createServer) for dev serving. Compatible component edits use HMR, preserving component instances and store state. Locale YAML edits replace the development catalogs while retaining the selected locale and existing subscriptions. Component directories, the setup module, and i18n sources are watched explicitly, including when they are outside the served static root.

Changes to setup files and component or locale file additions/removals perform a full page reload. An update that changes an incompatible browser contract, such as a component name or observed prop, also falls back to a full reload.

Use fe.publicDir to serve a directory of static assets at / without Vite transformations:

fe:
  publicDir: "./static"

The equivalent CLI option is rtgl fe watch --public-dir ./static. Relative paths are resolved from the project root. This is useful when binary assets use extensionless filenames that Vite would otherwise treat as JavaScript modules.

Vite Integration Details

FE keeps the same CLI interface and integrates Vite internally.

  • Virtual entry: FE generates a virtual module (virtual:rettangoli-fe-entry) from configured component files.
  • Plugin hooks used:
    • resolveId + load to provide generated entry code.
    • handleHotUpdate to route compatible component and locale edits through the FE virtual-entry HMR boundary.
    • configureServer middleware to serve the configured outfile path in watch mode and handle full-reload fallbacks.
  • Startup behavior:
    • Watch mode warms and validates the virtual entry before reporting the server as ready.
  • Output behavior:
    • Build preserves configured fe.outfile as the entry filename.
    • Additional chunks may be emitted under a chunks/ folder when splitting is enabled.
  • Validation behavior:
    • Contract validation and YAML/template parsing run before bundle generation.
    • Watched YAML changes invalidate the virtual entry before HMR processing.

Current limitation:

  • FE does not enable extra Vite CSS plugin configuration.

rtgl fe scaffold

Generates a new component with the required boilerplate files:

rtgl fe scaffold --category components --component-name my-component

--category is the folder name the component is created under (inside --dir, default ./example).

This creates:

./example/components/my-component/
  my-component.schema.yaml
  my-component.view.yaml
  my-component.store.js
  my-component.handlers.js

Each file contains a minimal valid template ready for editing.

rtgl fe check

Validates all components against the framework contracts. Checks include:

  • Every component has a .schema.yaml file
  • No forbidden API keys in .view.yaml (elementName, viewDataSchema, propsSchema, events, methods, attrsSchema)
  • No legacy dot property bindings in views
  • Schema methods match .methods.js exports

Text Output (default)

rtgl fe check

Outputs a grouped summary by rule and component, plus detailed error lines.

JSON Output

rtgl fe check --format json

Machine-readable JSON report for CI integration.

Error Codes

Code Description
RTGL-CONTRACT-001 Missing .schema.yaml for component
RTGL-CONTRACT-002 Forbidden API key in .view.yaml
RTGL-CONTRACT-003 Legacy dot property binding in view
RTGL-HANDLERS-001 handleBeforeMount returned a Promise
RTGL-HANDLERS-002 View references a missing handler
RTGL-METHODS-001 Method name is default
RTGL-METHODS-002 Method payload is not an object
RTGL-METHODS-003 Method conflicts with element property
RTGL-STORE-001 Action payload is not an object

rtgl fe examples

Generates example spec files from .schema.yaml examples for use with @rettangoli/vt visual testing.

rtgl fe examples

Output directory is configured in rettangoli.config.yaml:

fe:
  examples:
    outputDir: "./vt/specs/examples"

Configuration

All commands read from rettangoli.config.yaml at the project root:

fe:
  dirs:
    - "./src/components"
    - "./src/pages"
  setup: "setup.js"
  outfile: "./dist/bundle.js"
  publicDir: "./static"
  i18n:
    dir: "./src/i18n"
    defaultLocale: "en"
    fallbackLocale: "en"
    locales:
      - "en"
      - "vi"
  examples:
    outputDir: "./vt/specs/examples"
Key Description
dirs Directories to scan for component files
setup Setup script that exports custom dependencies
outfile Output path for the bundled JavaScript
publicDir Optional directory served at / without transformations in watch mode
i18n.dir Directory containing locale YAML files
i18n.defaultLocale Initial locale used by the runtime
i18n.fallbackLocale Locale used if another locale cannot be loaded
i18n.locales Supported locale codes
examples.outputDir Output directory for generated example specs

Setup File

The setup.js file exports a deps object that provides custom dependencies to your components. Dependencies are keyed by category (matching directory names under your configured dirs).

const deps = {
  components: {
    // available as deps.apiClient in component handlers
    apiClient: createApiClient(),
  },
  pages: {
    router: createRouter(),
  },
}

export { deps }

Each category's dependencies are merged into the deps argument that handlers receive. The framework handles virtual DOM and patching internally — setup.js is only for your application-level dependencies.

The generated entry imports the setup module before any component module. Bootstrap code that setup.js imports first, such as error reporting, therefore runs before component modules are evaluated and can observe their load-time errors.