Plugins
-
Intro § 1 -
Plugin Names § 2 -
API § 3 -
load § 3.1 -
normalize § 3.2 -
write § 3.3 -
onLayerEnd § 3.4 -
writeFile § 3.5 -
pluginBuilder § 3.6
Intro § 1
Plugin Names § 2
require(['foo!something/for/foo'], function (something) { //something is a reference to the resource //'something/for/foo' that was loaded by foo.js. });
require(['./foo!something/for/foo'], function (something) { });
require(['bar/foo!something/for/foo'], function (something) { });
API § 3
-
load : A function that is called to load a resource. This is the only mandatory API method that needs to be implemented for the plugin to be useful. -
normalize : A function to normalize the resource name. This is useful in providing optimal caching and optimization, but only needed if the resource name is not a module name. -
write : used by the optimizer to indicate when the plugin should write out a representation of the resource in the optimized file. -
pluginBuilder : A module name string for a module that should be used in the optimizer to do optimization work. That module is used instead of the plugin module when the optimizer runs.
load: function (name, parentRequire, onload, config)
§ 3.1
-
name : String. The name of the resource to load. This is the part after the ! separator in the name. So, if a module asks for 'foo!something/for/foo', the foo module's load function will receive 'something/for/foo' as the name. -
parentRequire : Function. A local "require" function to use to load other modules. This function will resolve relative module names relative to the module name that asked for this plugin resource. If the loader plugin wants to require() something relative to its own ID, it can ask for a require in its own define call. This require function has some utilities on it: -
parentRequire.toUrl(moduleResource) :where moduleResource is a module name plus an extension. For instance "view/templates/main.html". It will return a full path to the resource, obeying any RequireJS configuration. -
parentRequire.defined(moduleName) : Returns true if the module has already been loaded and defined. Used to be called require.isDefined before RequireJS 0.25.0. -
parentRequire.specified(moduleName) : Returns true if the module has already been requested or is in the process of loading and should be available at some point.
-
-
onload : Function. A function to call with the value for name. This tells the loader that the plugin is done loading the resource. onload.error() can be called, passing an error object to it, if the plugin detects an error condition that means the resource will fail to load correctly. -
config : Object. A configuration object. This is a way for the optimizer and the web app to pass configuration information to the plugin. The i18n! plugin uses this to get the current locale, if the web app wants to force a specific locale. The optimizer will set an isBuild property in the config to true if this plugin (or pluginBuilder) is being called as part of an optimizer build.
define({ load: function (name, req, onload, config) { //req has the same API as require(). req([name], function (value) { onload(value); }); } });
-
text : String. The string of JavaScript to evaluate.
define({ load: function (name, req, onload, config) { var url = req.toUrl(name + '.customFileExtension'), text; //Use a method to load the text (provided elsewhere) //by the plugin fetchText(url, function (text) { //Transform the text as appropriate for //the plugin by using a transform() //method provided elsewhere in the plugin. text = transform(text); //Have RequireJS execute the JavaScript within //the correct environment/context, and trigger the load //call for this resource. onload.fromText(text); }); } });
define({ load: function (name, req, onload, config) { if (config.isBuild) { //Indicate that the optimizer should not wait //for this resource any more and complete optimization. //This resource will be resolved dynamically during //run time in the web browser. onload(); } else { //Do something else that can be async. } } });
normalize: function (name, normalize)
§ 3.2
-
name : String. The resource name to normalize. -
normalize : Function. A function that can be called to normalize a regular module name.
define(['index!2?./a:./b:./c'], function (indexResource) { //indexResource will be the module that corresponds to './ c'. });
(function () { //Helper function to parse the 'N? value:value:value' //format used in the resource name. function parse(name) { var parts = name.split('?'), index = parseInt(parts[0], 10), choices = parts[1].split(':'), choice = choices[index]; return { index: index, choices: choices, choice: choice }; } //Main module definition. define({ normalize: function (name, normalize) { var parsed = parse(name), choices = parsed.choices; //Normalize each path choice. for (i = 0; i < choices.length; i++) { //Call the normalize() method passed in //to this function to normalize each //module name. choices[i] = normalize(choices[i]); } return parsed.index + '?' + choices.join(':'); }, load: function (name, req, onload, config) { req([parse(name).choice], function (value) { onload(value); }); } }); }());
write: function (pluginName, moduleName, write)
§ 3.3
-
pluginName : String. The normalized name for the plugin. Most plugins will not be authored with a name (they will be anonymous plugins) so it is useful to know the normalized name for the plugin module for use in the optimized file. -
moduleName : String. The normalized resource name. -
write : Function. A function to be called with a string of output to write to the optimized file. This function also contains a property function, write.asModule(moduleName, text) . asModule can be used to write out a module that may have an anonymous define call in there that needs name insertion or/and contains implicit require("") dependencies that need to be pulled out for the optimized file. asModule is useful for text transform plugins, like a CoffeeScript plugin.
write: function (pluginName, moduleName, write) { //The text plugin keeps a map of strings it fetched //during the build process, in a buildMap object. if (moduleName in buildMap) { //jsEscape is an internal method for the text plugin //that is used to make the string safe //for embedding in a JS string. var text = jsEscape(buildMap[moduleName]); write("define('" + pluginName + "!" + moduleName + "', function () { return '" + text + "';}); \n"); } }
onLayerEnd: function (write, data)
§ 3.4
-
write : Function. A function to be called with a string of output to write to the optimized layer. Modules should not be written out in this call. They will not be normalized correctly for coexistence with other define() calls already in the file. It is useful only for writing out non-define() code. -
data : Object. Information about the layer. Only has two properties: -
name : the module name of the layer. May be undefined. -
path : the file path of the layer. May be undefined, particularly if the output is just to a string that is consumed by another script.
-
writeFile: function (pluginName, name, parentRequire, write)
§ 3.5
-
pluginName : String. The normalized name for the plugin. Most plugins will not be authored with a name (they will be anonymous plugins) so it is useful to know the normalized name for the plugin module for use in the optimized file. -
name : String. The normalized resource name. -
parentRequire : Function. A local "require" function. The main use of this in writeFile is for calling parentRequire.toUrl() to generate file paths that are inside the build directory. -
write : Function. A function to be called with two arguments: -
fileName : String. The name of the file to write. You can use parentRequire.toUrl() with a relative path to generate a file name that will be inside the build output directory. -
text : String. The contents of the file. Must be UTF-8 encoded.
This function also contains a property function, write.asModule(moduleName, fileName, text) . asModule can be used to write out a module that may have an anonymous define call in there that needs name insertion or/and contains implicit require("") dependencies that need to be pulled out for the optimized file. -
pluginBuilder
§ 3.6
-
Do not use named modules for the plugin or the pluginBuilder. The pluginBuilder text contents are used instead of the contents of the plugin file, but that will only work if the files do not call define() with a name. -
Plugins and pluginBuilders that run as part of the build process have a very limited environment. The optimizer runs in a few different JS environments. Be careful of the environment assumptions if you want the plugin to run as part of the optimizer.