or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

amd-loader.mdbuild-system.mdcommand-line.mdconfiguration.mdindex.mdplugins.md

plugins.mddocs/

0

# Plugin System

1

2

RequireJS provides an extensible plugin system that allows loading and processing non-JavaScript resources such as text files, CSS, HTML templates, and other custom content types. Plugins transform resources during both development and build processes.

3

4

## Plugin Interface

5

6

All RequireJS plugins must implement a standardized interface for loading and processing resources.

7

8

### Core Plugin Methods

9

10

#### load()

11

Main method for loading and processing resources.

12

13

```javascript { .api }

14

load(name, require, onload, config)

15

```

16

17

**Parameters:**

18

- `name` (String) - Resource name/path (without plugin prefix)

19

- `require` (Function) - Local require function for loading dependencies

20

- `onload` (Function) - Callback to call when resource is loaded

21

- `config` (Object) - RequireJS configuration object

22

23

**Usage Example:**

24

25

```javascript

26

define({

27

load: function(name, require, onload, config) {

28

// Load and process the resource

29

const url = require.toUrl(name + '.txt');

30

31

// Fetch the resource

32

fetch(url).then(function(response) {

33

return response.text();

34

}).then(function(text) {

35

// Process the text and return result

36

onload(text.toUpperCase());

37

}).catch(function(error) {

38

onload.error(error);

39

});

40

}

41

});

42

```

43

44

#### write() (Build Support)

45

Optional method for writing optimized resources during build process.

46

47

```javascript { .api }

48

write(pluginName, moduleName, write, config)

49

```

50

51

**Parameters:**

52

- `pluginName` (String) - Name of the plugin

53

- `moduleName` (String) - Name of the resource being processed

54

- `write` (Function) - Function to call to write optimized content

55

- `config` (Object) - Build configuration object

56

57

**Usage Example:**

58

59

```javascript

60

define({

61

// Store processed content during build

62

buildMap: {},

63

64

load: function(name, require, onload, config) {

65

// Load and process resource

66

const processedContent = processResource(name);

67

68

// Store for build if needed

69

if (config.isBuild) {

70

this.buildMap[name] = processedContent;

71

}

72

73

onload(processedContent);

74

},

75

76

write: function(pluginName, moduleName, write, config) {

77

if (this.buildMap.hasOwnProperty(moduleName)) {

78

const content = this.buildMap[moduleName];

79

// Write as optimized module

80

write.asModule(pluginName + "!" + moduleName,

81

"define(function() { return " + JSON.stringify(content) + "; });");

82

}

83

}

84

});

85

```

86

87

#### normalize() (Optional)

88

Normalize resource names for consistent handling.

89

90

```javascript { .api }

91

normalize(name, normalize)

92

```

93

94

**Parameters:**

95

- `name` (String) - Resource name to normalize

96

- `normalize` (Function) - Normalization function provided by RequireJS

97

98

**Returns:** Normalized resource name

99

100

**Usage Example:**

101

102

```javascript

103

define({

104

normalize: function(name, normalize) {

105

// Remove file extension if present

106

if (name.substr(name.length - 4) === '.txt') {

107

name = name.substr(0, name.length - 4);

108

}

109

110

// Use RequireJS normalization

111

return normalize(name);

112

}

113

});

114

```

115

116

## Plugin Usage

117

118

### Loading Resources with Plugins

119

120

Use the plugin syntax `pluginName!resourceName` to load resources:

121

122

```javascript

123

// Load text file using text plugin

124

require(['text!templates/header.html'], function(headerHtml) {

125

document.getElementById('header').innerHTML = headerHtml;

126

});

127

128

// Load multiple resources

129

require(['text!data.json', 'text!template.html'], function(jsonText, templateHtml) {

130

const data = JSON.parse(jsonText);

131

// Use data and template

132

});

133

134

// Use in module definitions

135

define(['text!config.json'], function(configText) {

136

const config = JSON.parse(configText);

137

return {

138

apiUrl: config.apiUrl,

139

version: config.version

140

};

141

});

142

```

143

144

### Plugin Configuration

145

146

Configure plugin-specific options through RequireJS configuration:

147

148

```javascript

149

requirejs.config({

150

// Plugin-specific configuration

151

text: {

152

useXhr: function() {

153

// Force XHR usage in all environments

154

return true;

155

}

156

},

157

158

// Custom plugin configuration

159

myPlugin: {

160

processingOptions: {

161

minify: true,

162

stripComments: false

163

}

164

}

165

});

166

```

167

168

## Built-in Plugin Examples

169

170

### Text Plugin Pattern

171

172

A typical implementation for loading text resources:

173

174

```javascript

175

define(['module'], function(module) {

176

'use strict';

177

178

var fetchText = function(url, callback) {

179

// Environment-specific text fetching

180

if (typeof window !== 'undefined') {

181

// Browser implementation

182

var xhr = new XMLHttpRequest();

183

xhr.open('GET', url, true);

184

xhr.onreadystatechange = function() {

185

if (xhr.readyState === 4) {

186

callback(xhr.responseText);

187

}

188

};

189

xhr.send(null);

190

} else if (typeof process !== 'undefined') {

191

// Node.js implementation

192

var fs = require.nodeRequire('fs');

193

callback(fs.readFileSync(url, 'utf8'));

194

}

195

};

196

197

var buildMap = {};

198

199

return {

200

load: function(name, req, onload, config) {

201

var url = req.toUrl(name);

202

203

fetchText(url, function(text) {

204

// Store for build optimization

205

if (config.isBuild) {

206

buildMap[name] = text;

207

}

208

209

onload(text);

210

});

211

},

212

213

write: function(pluginName, moduleName, write, config) {

214

if (buildMap.hasOwnProperty(moduleName)) {

215

var text = buildMap[moduleName];

216

write.asModule(pluginName + "!" + moduleName,

217

"define(function() { return " + JSON.stringify(text) + "; });");

218

}

219

},

220

221

version: '1.0.0'

222

};

223

});

224

```

225

226

### JSON Plugin Example

227

228

```javascript

229

define({

230

load: function(name, req, onload, config) {

231

req(['text!' + name + '.json'], function(text) {

232

try {

233

onload(JSON.parse(text));

234

} catch (e) {

235

onload.error(new Error('Invalid JSON in ' + name + ': ' + e.message));

236

}

237

});

238

}

239

});

240

```

241

242

### CSS Plugin Example

243

244

```javascript

245

define({

246

load: function(name, req, onload, config) {

247

var url = req.toUrl(name + '.css');

248

249

if (typeof window !== 'undefined') {

250

// Browser: inject CSS via link tag

251

var link = document.createElement('link');

252

link.rel = 'stylesheet';

253

link.href = url;

254

link.onload = function() { onload(true); };

255

document.head.appendChild(link);

256

} else {

257

// Node.js: just signal completion

258

onload(true);

259

}

260

}

261

});

262

```

263

264

## Advanced Plugin Features

265

266

### Conditional Resource Loading

267

268

```javascript

269

define({

270

load: function(name, req, onload, config) {

271

// Check environment or feature availability

272

if (typeof window !== 'undefined' && window.WebGL) {

273

// Load WebGL version

274

req(['text!' + name + '.webgl.glsl'], onload);

275

} else {

276

// Load fallback version

277

req(['text!' + name + '.fallback.txt'], onload);

278

}

279

}

280

});

281

```

282

283

### Resource Transformation

284

285

```javascript

286

define({

287

load: function(name, req, onload, config) {

288

req(['text!' + name + '.template'], function(template) {

289

// Transform template (e.g., precompile Handlebars)

290

const compiled = Handlebars.compile(template);

291

onload(compiled);

292

});

293

},

294

295

write: function(pluginName, moduleName, write, config) {

296

// Write precompiled template to build

297

if (buildMap.hasOwnProperty(moduleName)) {

298

const compiledTemplate = buildMap[moduleName];

299

write.asModule(pluginName + "!" + moduleName,

300

"define(['handlebars'], function(Handlebars) { return " +

301

compiledTemplate.toString() + "; });");

302

}

303

}

304

});

305

```

306

307

### Error Handling

308

309

```javascript

310

define({

311

load: function(name, req, onload, config) {

312

const url = req.toUrl(name);

313

314

fetchResource(url, function(result, error) {

315

if (error) {

316

// Signal error to RequireJS

317

onload.error(new Error('Failed to load ' + name + ': ' + error.message));

318

} else {

319

onload(result);

320

}

321

});

322

}

323

});

324

```

325

326

## Build System Integration

327

328

### Plugin Optimization

329

330

Plugins can be optimized during the build process to improve runtime performance:

331

332

```javascript

333

// Build configuration

334

{

335

// Replace plugin calls with static content

336

stubModules: ['text', 'json'],

337

338

// Optimize all plugin resources

339

optimizeAllPluginResources: true,

340

341

// Plugin-specific build settings

342

inlineText: true // Inline text! resources

343

}

344

```

345

346

### Build-Time Resource Processing

347

348

```javascript

349

define({

350

load: function(name, req, onload, config) {

351

req(['text!' + name], function(content) {

352

let processed = content;

353

354

if (config.isBuild) {

355

// Build-time processing (minification, compilation, etc.)

356

processed = minifyContent(content);

357

buildMap[name] = processed;

358

}

359

360

onload(processed);

361

});

362

},

363

364

write: function(pluginName, moduleName, write, config) {

365

if (buildMap.hasOwnProperty(moduleName)) {

366

write.asModule(pluginName + "!" + moduleName,

367

"define(function() { return " + JSON.stringify(buildMap[moduleName]) + "; });");

368

}

369

}

370

});

371

```

372

373

## Plugin Development Best Practices

374

375

### Environment Detection

376

377

```javascript

378

define({

379

load: function(name, req, onload, config) {

380

if (typeof window !== 'undefined') {

381

// Browser environment

382

loadViaBrowser(name, req, onload);

383

} else if (typeof process !== 'undefined') {

384

// Node.js environment

385

loadViaNode(name, req, onload);

386

} else {

387

// Other environments (Rhino, Nashorn, etc.)

388

loadViaGeneric(name, req, onload);

389

}

390

}

391

});

392

```

393

394

### Resource Caching

395

396

```javascript

397

define({

398

cache: {},

399

400

load: function(name, req, onload, config) {

401

if (this.cache[name]) {

402

// Return cached result

403

onload(this.cache[name]);

404

return;

405

}

406

407

// Load and cache

408

loadResource(name, req, function(result) {

409

this.cache[name] = result;

410

onload(result);

411

}.bind(this));

412

}

413

});

414

```

415

416

### Version Management

417

418

```javascript

419

define({

420

version: '2.1.0',

421

422

load: function(name, req, onload, config) {

423

// Plugin implementation

424

},

425

426

// Optional: API compatibility check

427

loadingFinished: function() {

428

console.log('Plugin v' + this.version + ' loaded successfully');

429

}

430

});

431

```

432

433

## Types

434

435

```javascript { .api }

436

interface RequirePlugin {

437

load(name: string, require: Function, onload: Function, config: Object): void;

438

normalize?(name: string, normalize: Function): string;

439

write?(pluginName: string, moduleName: string, write: Function, config: Object): void;

440

version?: string;

441

}

442

443

interface PluginOnload extends Function {

444

(result: any): void;

445

error(err: Error): void;

446

fromText(name: string, text: string): void;

447

}

448

449

interface PluginWrite extends Function {

450

(content: string): void;

451

asModule(moduleName: string, content: string): void;

452

}

453

```

454

455

The RequireJS plugin system provides a powerful foundation for extending module loading capabilities, enabling seamless integration of various resource types and custom processing logic into AMD-based applications.