CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-riot

Simple and elegant component-based UI library

Pending
Overview
Eval results
Files

compilation.mddocs/

Compilation

Runtime compilation capabilities for compiling riot components from templates and URLs. Available only in the riot+compiler build, these functions enable dynamic component compilation and template processing in the browser.

Capabilities

Compile DOM Scripts

Automatically discovers and compiles riot script tags in the DOM.

/**
 * Compile riot script tags found in the DOM
 * @param options - Optional compilation configuration
 * @returns Promise that resolves when all scripts are compiled and registered
 */
function compile(options?: CompileOptions): Promise<void>;

Usage Example:

<!-- HTML with riot script tags -->
<script type="riot" src="./components/my-timer.riot"></script>
<script type="riot" data-src="./components/my-widget.riot"></script>
import { compile, mount } from "riot+compiler";

// Compile all riot script tags and register components
await compile({ 
  // Optional compilation options
  compact: true,
  expression: "javascript"
});

// Components are now registered and can be mounted
mount("my-timer");
mount("my-widget");

Compile from String

Compiles a riot component from a template string.

/**
 * Compile riot component from string template
 * @param string - Component template string
 * @param options - Optional compilation configuration
 * @returns Compilation result with code and metadata
 */
function compileFromString(
  string: string, 
  options?: CompileOptions
): CompilationResult;

Usage Example:

import { compileFromString, register } from "riot+compiler";

const template = `
<my-dynamic-component>
  <h1>{ props.title }</h1>
  <p>Generated at: { state.timestamp }</p>
  
  <script>
    export default {
      onBeforeMount() {
        this.state = { timestamp: new Date().toISOString() };
      }
    }
  </script>
  
  <style>
    my-dynamic-component {
      padding: 1rem;
      border: 1px solid #ccc;
    }
  </style>
</my-dynamic-component>
`;

// Compile the template
const result = compileFromString(template, {
  file: 'dynamic-component.riot'
});

// Register the compiled component
register("my-dynamic-component", eval(result.code));

Compile from URL

Fetches and compiles a riot component from a URL.

/**
 * Compile riot component from URL
 * @param url - URL to fetch component template from
 * @param options - Optional compilation configuration
 * @returns Promise with compilation result
 */
function compileFromUrl(
  url: string, 
  options?: CompileOptions
): Promise<CompilationResult>;

Usage Example:

import { compileFromUrl, register } from "riot+compiler";

// Fetch and compile remote component
const result = await compileFromUrl("https://example.com/components/remote-widget.riot", {
  compact: false,
  expression: "javascript"
});

// Register the compiled component
register("remote-widget", eval(result.code));

// Mount the component
mount("remote-widget", { apiKey: "abc123" });

Inject Compiled Component

Evaluates and registers compiled component code in the global registry.

/**
 * Inject compiled component code into global registry
 * @param code - Compiled component JavaScript code
 * @param tagName - Component tag name for registration
 * @param url - Source URL for debugging/error reporting
 * @returns void
 */
function inject(code: string, tagName: string, url: string): void;

Usage Example:

import { inject } from "riot+compiler";

// Manually inject pre-compiled code
const compiledCode = `({
  css: 'injected-component { color: red; }',
  template: (template) => template('<h1>Injected!</h1>'),
  exports: {
    onMounted() {
      console.log('Injected component mounted');
    }
  }
})`;

inject(compiledCode, "injected-component", "manual-injection");

// Component is now registered and ready to mount
mount("injected-component");

Enhanced Mounting with Slots

The compiler build provides enhanced versions of mount and component that automatically create slots from DOM content:

Enhanced Mount

/**
 * Enhanced mounting function that creates slots from DOM content
 * @param selector - CSS selector or HTMLElement to mount to
 * @param initialProps - Initial component properties
 * @param componentName - Optional component name
 * @returns Array of component instances
 */
function mount<Props, State>(
  selector: string | HTMLElement,
  initialProps?: Props,
  componentName?: string
): RiotComponent<Props, State>[];

Usage Example:

<!-- Existing DOM content becomes slots -->
<my-card>
  <div slot="header">Card Title</div>
  <div slot="content">Card content goes here</div>
</my-card>
import { mount } from "riot+compiler";

// DOM content is automatically converted to slots
const cards = mount("my-card", { theme: "dark" });

Enhanced Component Factory

/**
 * Enhanced component factory with automatic slot creation
 * @param wrapper - Component wrapper implementation
 * @returns Enhanced factory function
 */
function component(wrapper: RiotComponentWrapper): (
  el: HTMLElement,
  props?: any,
  meta?: ComponentMeta
) => RiotComponent;

Compilation Options

interface CompileOptions {
  /** Generate compact output (minified) */
  compact?: boolean;
  
  /** Expression parser type */
  expression?: "javascript" | "typescript";
  
  /** File path for source maps and error reporting */
  file?: string;
  
  /** Custom preprocessors */
  preprocessors?: {
    [key: string]: PreprocessorFunction;
  };
  
  /** Template parser options */
  template?: TemplateOptions;
  
  /** CSS parser options */
  css?: CSSOptions;
}

interface CompilationResult {
  /** Compiled JavaScript code */
  code: string;
  
  /** Component metadata */
  meta: {
    tagName: string;
    dependencies?: string[];
    css?: boolean;
    javascript?: boolean;
  };
  
  /** Source map (if enabled) */
  map?: string;
}

Advanced Compilation Patterns

Dynamic Component Loading

import { compileFromUrl, register, mount } from "riot+compiler";

class ComponentLoader {
  constructor() {
    this.cache = new Map();
  }
  
  async loadComponent(name, url) {
    if (this.cache.has(name)) {
      return this.cache.get(name);
    }
    
    try {
      const result = await compileFromUrl(url);
      const component = eval(result.code);
      
      register(name, component);
      this.cache.set(name, component);
      
      return component;
    } catch (error) {
      console.error(`Failed to load component ${name}:`, error);
      throw error;
    }
  }
  
  async loadAndMount(name, url, selector, props) {
    await this.loadComponent(name, url);
    return mount(selector, props, name);
  }
}

// Usage
const loader = new ComponentLoader();
await loader.loadAndMount(
  "lazy-widget", 
  "/components/lazy-widget.riot",
  ".widget-container",
  { data: apiData }
);

Template Preprocessing

import { compileFromString } from "riot+compiler";

// Template with custom preprocessing
const preprocessTemplate = (template, context) => {
  return template
    .replace(/\{\{(\w+)\}\}/g, '{ $1 }')  // Convert {{}} to {}
    .replace(/\$\{(\w+)\}/g, '{ props.$1 }'); // Convert ${} to props
};

const rawTemplate = `
<preprocessed-component>
  <h1>{{title}}</h1>
  <p>Value: \${value}</p>
</preprocessed-component>
`;

const processedTemplate = preprocessTemplate(rawTemplate);
const result = compileFromString(processedTemplate);

Types

type CompileOptions = {
  compact?: boolean;
  expression?: "javascript" | "typescript";
  file?: string;
  preprocessors?: Record<string, PreprocessorFunction>;
  template?: TemplateOptions;
  css?: CSSOptions;
};

type CompilationResult = {
  code: string;
  meta: {
    tagName: string;
    dependencies?: string[];
    css?: boolean;
    javascript?: boolean;
  };
  map?: string;
};

type PreprocessorFunction = (
  code: string,
  options: any
) => { code: string; map?: string };

type TemplateOptions = {
  brackets?: [string, string];
  [key: string]: any;
};

type CSSOptions = {
  parser?: string;
  [key: string]: any;
};

Install with Tessl CLI

npx tessl i tessl/npm-riot

docs

compilation.md

component-factory.md

component-registration.md

index.md

mounting-lifecycle.md

plugin-system.md

pure-components.md

utilities.md

tile.json