or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compilation.mdcomponent-factory.mdcomponent-registration.mdindex.mdmounting-lifecycle.mdplugin-system.mdpure-components.mdutilities.md

compilation.mddocs/

0

# Compilation

1

2

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.

3

4

## Capabilities

5

6

### Compile DOM Scripts

7

8

Automatically discovers and compiles riot script tags in the DOM.

9

10

```typescript { .api }

11

/**

12

* Compile riot script tags found in the DOM

13

* @param options - Optional compilation configuration

14

* @returns Promise that resolves when all scripts are compiled and registered

15

*/

16

function compile(options?: CompileOptions): Promise<void>;

17

```

18

19

**Usage Example:**

20

21

```html

22

<!-- HTML with riot script tags -->

23

<script type="riot" src="./components/my-timer.riot"></script>

24

<script type="riot" data-src="./components/my-widget.riot"></script>

25

```

26

27

```javascript

28

import { compile, mount } from "riot+compiler";

29

30

// Compile all riot script tags and register components

31

await compile({

32

// Optional compilation options

33

compact: true,

34

expression: "javascript"

35

});

36

37

// Components are now registered and can be mounted

38

mount("my-timer");

39

mount("my-widget");

40

```

41

42

### Compile from String

43

44

Compiles a riot component from a template string.

45

46

```typescript { .api }

47

/**

48

* Compile riot component from string template

49

* @param string - Component template string

50

* @param options - Optional compilation configuration

51

* @returns Compilation result with code and metadata

52

*/

53

function compileFromString(

54

string: string,

55

options?: CompileOptions

56

): CompilationResult;

57

```

58

59

**Usage Example:**

60

61

```javascript

62

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

63

64

const template = `

65

<my-dynamic-component>

66

<h1>{ props.title }</h1>

67

<p>Generated at: { state.timestamp }</p>

68

69

<script>

70

export default {

71

onBeforeMount() {

72

this.state = { timestamp: new Date().toISOString() };

73

}

74

}

75

</script>

76

77

<style>

78

my-dynamic-component {

79

padding: 1rem;

80

border: 1px solid #ccc;

81

}

82

</style>

83

</my-dynamic-component>

84

`;

85

86

// Compile the template

87

const result = compileFromString(template, {

88

file: 'dynamic-component.riot'

89

});

90

91

// Register the compiled component

92

register("my-dynamic-component", eval(result.code));

93

```

94

95

### Compile from URL

96

97

Fetches and compiles a riot component from a URL.

98

99

```typescript { .api }

100

/**

101

* Compile riot component from URL

102

* @param url - URL to fetch component template from

103

* @param options - Optional compilation configuration

104

* @returns Promise with compilation result

105

*/

106

function compileFromUrl(

107

url: string,

108

options?: CompileOptions

109

): Promise<CompilationResult>;

110

```

111

112

**Usage Example:**

113

114

```javascript

115

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

116

117

// Fetch and compile remote component

118

const result = await compileFromUrl("https://example.com/components/remote-widget.riot", {

119

compact: false,

120

expression: "javascript"

121

});

122

123

// Register the compiled component

124

register("remote-widget", eval(result.code));

125

126

// Mount the component

127

mount("remote-widget", { apiKey: "abc123" });

128

```

129

130

### Inject Compiled Component

131

132

Evaluates and registers compiled component code in the global registry.

133

134

```typescript { .api }

135

/**

136

* Inject compiled component code into global registry

137

* @param code - Compiled component JavaScript code

138

* @param tagName - Component tag name for registration

139

* @param url - Source URL for debugging/error reporting

140

* @returns void

141

*/

142

function inject(code: string, tagName: string, url: string): void;

143

```

144

145

**Usage Example:**

146

147

```javascript

148

import { inject } from "riot+compiler";

149

150

// Manually inject pre-compiled code

151

const compiledCode = `({

152

css: 'injected-component { color: red; }',

153

template: (template) => template('<h1>Injected!</h1>'),

154

exports: {

155

onMounted() {

156

console.log('Injected component mounted');

157

}

158

}

159

})`;

160

161

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

162

163

// Component is now registered and ready to mount

164

mount("injected-component");

165

```

166

167

## Enhanced Mounting with Slots

168

169

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

170

171

### Enhanced Mount

172

173

```typescript { .api }

174

/**

175

* Enhanced mounting function that creates slots from DOM content

176

* @param selector - CSS selector or HTMLElement to mount to

177

* @param initialProps - Initial component properties

178

* @param componentName - Optional component name

179

* @returns Array of component instances

180

*/

181

function mount<Props, State>(

182

selector: string | HTMLElement,

183

initialProps?: Props,

184

componentName?: string

185

): RiotComponent<Props, State>[];

186

```

187

188

**Usage Example:**

189

190

```html

191

<!-- Existing DOM content becomes slots -->

192

<my-card>

193

<div slot="header">Card Title</div>

194

<div slot="content">Card content goes here</div>

195

</my-card>

196

```

197

198

```javascript

199

import { mount } from "riot+compiler";

200

201

// DOM content is automatically converted to slots

202

const cards = mount("my-card", { theme: "dark" });

203

```

204

205

### Enhanced Component Factory

206

207

```typescript { .api }

208

/**

209

* Enhanced component factory with automatic slot creation

210

* @param wrapper - Component wrapper implementation

211

* @returns Enhanced factory function

212

*/

213

function component(wrapper: RiotComponentWrapper): (

214

el: HTMLElement,

215

props?: any,

216

meta?: ComponentMeta

217

) => RiotComponent;

218

```

219

220

## Compilation Options

221

222

```typescript { .api }

223

interface CompileOptions {

224

/** Generate compact output (minified) */

225

compact?: boolean;

226

227

/** Expression parser type */

228

expression?: "javascript" | "typescript";

229

230

/** File path for source maps and error reporting */

231

file?: string;

232

233

/** Custom preprocessors */

234

preprocessors?: {

235

[key: string]: PreprocessorFunction;

236

};

237

238

/** Template parser options */

239

template?: TemplateOptions;

240

241

/** CSS parser options */

242

css?: CSSOptions;

243

}

244

245

interface CompilationResult {

246

/** Compiled JavaScript code */

247

code: string;

248

249

/** Component metadata */

250

meta: {

251

tagName: string;

252

dependencies?: string[];

253

css?: boolean;

254

javascript?: boolean;

255

};

256

257

/** Source map (if enabled) */

258

map?: string;

259

}

260

```

261

262

## Advanced Compilation Patterns

263

264

### Dynamic Component Loading

265

266

```javascript

267

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

268

269

class ComponentLoader {

270

constructor() {

271

this.cache = new Map();

272

}

273

274

async loadComponent(name, url) {

275

if (this.cache.has(name)) {

276

return this.cache.get(name);

277

}

278

279

try {

280

const result = await compileFromUrl(url);

281

const component = eval(result.code);

282

283

register(name, component);

284

this.cache.set(name, component);

285

286

return component;

287

} catch (error) {

288

console.error(`Failed to load component ${name}:`, error);

289

throw error;

290

}

291

}

292

293

async loadAndMount(name, url, selector, props) {

294

await this.loadComponent(name, url);

295

return mount(selector, props, name);

296

}

297

}

298

299

// Usage

300

const loader = new ComponentLoader();

301

await loader.loadAndMount(

302

"lazy-widget",

303

"/components/lazy-widget.riot",

304

".widget-container",

305

{ data: apiData }

306

);

307

```

308

309

### Template Preprocessing

310

311

```javascript

312

import { compileFromString } from "riot+compiler";

313

314

// Template with custom preprocessing

315

const preprocessTemplate = (template, context) => {

316

return template

317

.replace(/\{\{(\w+)\}\}/g, '{ $1 }') // Convert {{}} to {}

318

.replace(/\$\{(\w+)\}/g, '{ props.$1 }'); // Convert ${} to props

319

};

320

321

const rawTemplate = `

322

<preprocessed-component>

323

<h1>{{title}}</h1>

324

<p>Value: \${value}</p>

325

</preprocessed-component>

326

`;

327

328

const processedTemplate = preprocessTemplate(rawTemplate);

329

const result = compileFromString(processedTemplate);

330

```

331

332

## Types

333

334

```typescript { .api }

335

type CompileOptions = {

336

compact?: boolean;

337

expression?: "javascript" | "typescript";

338

file?: string;

339

preprocessors?: Record<string, PreprocessorFunction>;

340

template?: TemplateOptions;

341

css?: CSSOptions;

342

};

343

344

type CompilationResult = {

345

code: string;

346

meta: {

347

tagName: string;

348

dependencies?: string[];

349

css?: boolean;

350

javascript?: boolean;

351

};

352

map?: string;

353

};

354

355

type PreprocessorFunction = (

356

code: string,

357

options: any

358

) => { code: string; map?: string };

359

360

type TemplateOptions = {

361

brackets?: [string, string];

362

[key: string]: any;

363

};

364

365

type CSSOptions = {

366

parser?: string;

367

[key: string]: any;

368

};

369

```