create.mustache revision 9d2003304196a2769a38dca27c76e4fda1e875b0
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>In this example we will show you our recommended approach to creating your own `YUI` modules.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h2 id="what">What is a module?</h2>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>A `YUI` module can be described as <em>"any code that can be separated to run on it's own"</em>.
9d2003304196a2769a38dca27c76e4fda1e875b0Dav GlassMany times, this code can be reusable in different ways.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h3 id="define">How is a module defined?</h3>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h2 id="know">How does YUI know about a module?</h2>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>`YUI` gives you a few options on how to tell it about your modules. The simpliest way is to include your modules
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glasson the page after the `YUI` seed file.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h3 id="local">Local modules</h3>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>If all of your modules are wrapped in a valid `YUI.add` call, `YUI` will know about them just
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassbecause they are on the page. The calls to `YUI.add` tell the `YUI` seed all that it needs to know
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassabout your modules and registers them with the system.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<script src="/path/to/yui-min.js"></script>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<script src="/path/to/my/module1.js"></script>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<script src="/path/to/my/module2.js"></script>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<script src="/path/to/my/module3.js"></script>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>Once available, they can be <em>used</em> as you would expect:</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav GlassYUI().use('module1', 'module2', 'module3', function(Y) {
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h3 id="config">Configured simple modules</h3>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>The local use case may not be good for you if you have several modules that you would like `YUI` to know about.
9d2003304196a2769a38dca27c76e4fda1e875b0Dav GlassIn this case, you would want to tell `YUI` about your modules so that it can fetch them when they are required.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>To do this, you need to use one of the <a href="index.html#config">various ways to configure</a> `YUI` and
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glasstell it about your modules.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>In this example, we will use the `YUI.GlobalConfig` to tell all `YUI` instances about our modules:</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass requires: [ 'node', 'event', 'dd', 'yql']
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>Now that we have told `YUI` about our modules, we can simply use them:</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav GlassYUI().use('module1', 'module2', 'module3', function(Y) {
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>The advantage of this approach is that we now have all of our modules information in one simple location
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassthat can be created by a build script and will be much easier to maintain.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h3 id="structured">Structured Modules</h3>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>In larger projects, you may need to structure your modules in a common way if you have multiple developers working
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glasson the code. In this case, you can follow `YUI`'s modal on this and structure your code to get the most use
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassout of Loader.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>When creating a module like the ones above, you can create your built files like this:</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>Now that your files are structed in a parsable manner, `Loader` can handle them without much of a configuration.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h4>Local static files</h4>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass ourmodules: {
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass base: '/ourmodules/',
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass module1: {},
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass module2: {},
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass requires: [ 'node', 'event', 'dd', 'yql']
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>By default, when `Loader` is attempting to fetch a static module, it will create a url using a few config options:
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass`base` and the `modulename` that was requested.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass /<base>/<modulename>/<modulename>(-<filter>).js
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>Now when you `use` your modules, `Loader` will find them and load them dynamically.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h4>Using a ComboHandler</h4>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>There are several combo handlers for different languages, so we won't discuss them here. Basically
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassa combo handler is an entry point on your server that accepts a query string of a list of files. The
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassserver then combines all those files and returns the output. This allows you to ask for multiple files
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassbut only use a few HTTP requests to fetch them.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>`YUI` has always had this support built in for it's core files, but you can have this with your modules too.
9d2003304196a2769a38dca27c76e4fda1e875b0Dav GlassConfiguring `YUI` to use a custom combo handler is extremely easy, let's modify the above example to use a
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glasscombo server that's located here: `/my-combo`</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass ourmodules: {
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass base: '/ourmodules/',
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass combine: true,
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass comboBase: '/my-combo?',
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass comboSep: ';', //Defaults to &
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass module1: {},
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass module2: {},
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass requires: [ 'node', 'event', 'dd', 'yql']
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>When `Loader` is attempting to fetch a set of combined modules, it will create a url using these config options:
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass`root`, `comboBase`, `comboSep` and the `<modulename>`'s that were requested.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass <comboBase><root><modulename>/<modulename>(-<filter>).js<comboSep><root><modulename>/<modulename>(-<filter>).js
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass /my-combo?module1/module1.js;module2/module2.js;/module2/module3.js
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>Now you have a flexible, scalable and dynamic module loading system that will let you build large scale
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassapplications or simple websites.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h2>Builder</h2>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>If you want to dynamically create the `-min`, `-debug` files inside your project, take a look
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassat our `Ant` based build system tool called <a href="https://github.com/yui/builder/">builder</a>.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<h2>Custom Aliases</h2>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>`YUI` uses <em>aliases</em> under the hood as module "shortcuts", for example, when you `use` "node"
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass`Loader` doesn't fetch a `node.js` file, it actually fetches several files under the hood that make up the "node"
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glassalias. You can use this too with your custom modules:</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass ourmodules: {
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass use: [ 'module1', 'module2', 'module3' ]
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass requires: [ 'all' ]
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass<p>This will create an alias called `all` for the modules: `'module1', 'module2', 'module3'`. You can then
9d2003304196a2769a38dca27c76e4fda1e875b0Dav Glass`use` that module as you normally would. You can even use that module as a requirement for other modules.</p>
9d2003304196a2769a38dca27c76e4fda1e875b0Dav GlassYUI().use('all');
9d2003304196a2769a38dca27c76e4fda1e875b0Dav GlassYUI().use('foo');