RequireJS extensible plugin system for loading non-JavaScript resources and custom module types. Plugins enable loading text files, CSS, images, and other resources through the module system.
Load resources using plugin syntax with exclamation mark notation.
// Plugin loading syntax
require(['pluginName!resourcePath'], function(resource) {
// Use loaded resource
});
// Common plugin patterns
require(['text!template.html'], function(template) {
// template contains file contents as string
});
require(['css!styles.css'], function() {
// CSS loaded and applied to page
});
require(['json!data.json'], function(data) {
// JSON parsed and returned as object
});Usage Examples:
// Load HTML template
require(['text!templates/user.html'], function(userTemplate) {
document.getElementById('content').innerHTML = userTemplate;
});
// Load CSS stylesheet
require(['css!themes/dark.css'], function() {
console.log('Dark theme loaded');
});
// Load JSON configuration
require(['json!config/settings.json'], function(settings) {
console.log('API URL:', settings.apiUrl);
console.log('Timeout:', settings.timeout);
});
// Multiple plugin resources
require([
'text!templates/header.html',
'text!templates/footer.html',
'css!styles/layout.css'
], function(headerTmpl, footerTmpl) {
renderPage(headerTmpl, footerTmpl);
});Create custom plugins to handle specific resource types.
/**
* Plugin definition interface
*/
interface RequirePlugin {
/** Load and process a resource */
load(name: string, req: LocalRequire, onload: (value: any) => void, config: any): void;
/** Normalize resource names */
normalize?(name: string, normalize: (name: string) => string): string;
/** Build-time resource processing */
write?(pluginName: string, moduleName: string, write: WriteAPI): void;
/** Alternative build-time processing */
writeFile?(pluginName: string, name: string, req: LocalRequire, write: WriteFileAPI, config: any): void;
/** Plugin initialization */
pluginBuilder?: string;
}
/**
* Load function parameters
*/
interface LoadParameters {
/** Resource name after normalization */
name: string;
/** Local require function */
req: LocalRequire;
/** Success callback */
onload: (value: any) => void;
/** RequireJS configuration */
config: any;
}
interface LocalRequire {
(moduleId: string): any;
toUrl(moduleNamePlusExt: string): string;
}Usage Examples:
// Simple text loader plugin
define('text', [], function() {
return {
load: function(name, req, onload, config) {
var url = req.toUrl(name);
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
onload(xhr.responseText);
} else {
onload.error(new Error('Failed to load: ' + url));
}
}
};
xhr.send();
}
};
});
// JSON loader plugin
define('json', [], function() {
return {
load: function(name, req, onload, config) {
var url = req.toUrl(name + '.json');
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
var data = JSON.parse(xhr.responseText);
onload(data);
} catch (e) {
onload.error(e);
}
} else {
onload.error(new Error('HTTP ' + xhr.status + ': ' + url));
}
}
};
xhr.send();
}
};
});
// Image loader plugin
define('image', [], function() {
return {
load: function(name, req, onload, config) {
var url = req.toUrl(name);
var img = new Image();
img.onload = function() {
onload(img);
};
img.onerror = function() {
onload.error(new Error('Failed to load image: ' + url));
};
img.src = url;
}
};
});Normalize resource names and handle relative paths.
/**
* Normalize function for plugins
*/
interface NormalizeFunction {
/**
* Normalize resource name
* @param name - Resource name to normalize
* @param normalize - Function to normalize module names
* @returns Normalized resource name
*/
normalize(name: string, normalize: (name: string) => string): string;
}Usage Examples:
// Plugin with normalization
define('template', [], function() {
return {
normalize: function(name, normalize) {
// Add .html extension if missing
if (!/\.html$/.test(name)) {
name += '.html';
}
// Handle relative paths
return normalize(name);
},
load: function(name, req, onload, config) {
// name is already normalized
var url = req.toUrl(name);
// Load logic...
}
};
});
// Usage with normalization
require(['template!user'], function(template) {
// Loads 'user.html' template
});
require(['template!../shared/header'], function(template) {
// Resolves relative path and loads 'header.html'
});Handle plugin resources during build optimization.
/**
* Build-time processing interfaces
*/
interface WriteAPI {
/** Write module as AMD module */
asModule(moduleName: string, contents: string): void;
/** Write raw contents */
(contents: string): void;
}
interface WriteFileAPI {
/** Write file to build output */
(filename: string, contents: string): void;
}
/**
* Build configuration for plugins
*/
interface PluginBuildConfig {
/** Stub out plugin calls in built code */
stubModules?: string[];
/** Optimize all plugin resources */
optimizeAllPluginResources?: boolean;
/** Inline plugin resources */
inlineText?: boolean;
}Usage Examples:
// Plugin with build support
define('template', [], function() {
return {
load: function(name, req, onload, config) {
// Runtime loading
var url = req.toUrl(name + '.html');
// ... xhr loading logic
},
write: function(pluginName, moduleName, write) {
// Build-time processing
write.asModule(moduleName,
'define("' + moduleName + '", function() {\n' +
' return ' + JSON.stringify(template) + ';\n' +
'});'
);
}
};
});
// CSS plugin with build processing
define('css', [], function() {
return {
load: function(name, req, onload, config) {
var url = req.toUrl(name + '.css');
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
onload();
},
writeFile: function(pluginName, name, req, write, config) {
// Read CSS file and write to build
var cssContent = req.toUrl(name + '.css');
write('css/' + name + '.css', cssContent);
}
};
});
// Build configuration
({
baseUrl: 'src',
name: 'main',
out: 'built.js',
// Preserve text plugin calls
stubModules: ['text'],
// Inline text resources
inlineText: true,
// Optimize plugin resources
optimizeAllPluginResources: true
})RequireJS ecosystem plugins for common resource types.
// Text plugin (requirejs-text)
require(['text!template.html'], function(html) {
// HTML content as string
});
// CSS plugin (require-css)
require(['css!stylesheet.css'], function() {
// CSS loaded and applied
});
// Domready plugin (requirejs-domready)
require(['domReady!'], function(doc) {
// DOM is ready
});
// Order plugin (requirejs-order)
require(['order!lib1.js', 'order!lib2.js'], function() {
// Scripts loaded in order
});
// Font plugin (requirejs-font)
require(['font!OpenSans'], function() {
// Web font loaded
});Usage Examples:
// Complex plugin combination
require([
'domReady!',
'text!templates/app.html',
'css!styles/app.css',
'json!config/settings.json'
], function(doc, appTemplate, settings) {
// DOM ready, template loaded, CSS applied, settings loaded
initializeApp(doc, appTemplate, settings);
});
// Conditional plugin loading
require(['has!webgl?webgl-plugin!shaders/vertex.glsl:canvas2d-plugin!sprites.json'],
function(resource) {
// Loads different resources based on feature detection
}
);
// Plugin chaining
require(['text!markdown!content/article.md'], function(html) {
// Markdown processed to HTML
});Handle plugin loading failures and errors.
/**
* Plugin error handling
*/
interface PluginErrorHandling {
/** Error callback for plugin loading */
onload.error(error: Error): void;
/** Plugin-specific error types */
errors: {
network: "Network error loading resource";
parse: "Error parsing resource content";
notfound: "Resource not found";
timeout: "Resource loading timeout";
};
}Usage Examples:
// Plugin with error handling
define('data', [], function() {
return {
load: function(name, req, onload, config) {
var url = req.toUrl(name + '.json');
var xhr = new XMLHttpRequest();
var timeout = config.dataTimeout || 5000;
var timeoutId = setTimeout(function() {
xhr.abort();
onload.error(new Error('Timeout loading: ' + url));
}, timeout);
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
clearTimeout(timeoutId);
if (xhr.status === 200) {
try {
onload(JSON.parse(xhr.responseText));
} catch (e) {
onload.error(new Error('Parse error: ' + e.message));
}
} else if (xhr.status === 404) {
onload.error(new Error('Resource not found: ' + url));
} else {
onload.error(new Error('HTTP ' + xhr.status + ': ' + url));
}
}
};
xhr.onerror = function() {
clearTimeout(timeoutId);
onload.error(new Error('Network error loading: ' + url));
};
xhr.send();
}
};
});
// Using plugin with error handling
require(['data!config'],
function(config) {
console.log('Config loaded:', config);
},
function(err) {
console.error('Failed to load config:', err.message);
// Use default configuration
useDefaultConfig();
}
);// Plugin system types
interface PluginRegistry {
[pluginName: string]: RequirePlugin;
}
interface PluginContext {
config: any;
req: LocalRequire;
defined: { [key: string]: any };
waiting: { [key: string]: boolean };
}
interface PluginLoadEvent {
pluginName: string;
resourceName: string;
url: string;
startTime: number;
endTime?: number;
error?: Error;
}
// Build-time plugin types
interface PluginBuildContext {
optimize: string;
inlineText: boolean;
stubModules: string[];
config: any;
}
interface PluginResource {
pluginName: string;
resourceName: string;
content: string;
url: string;
buildPath?: string;
}