API Docs for: 0.2.0
Show:

File: lib/origin.js

/*
 * Copyright (c) 2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint node:true, nomen: true */

/**
Provides a set of features to mutate the express app into an origin server for yui
modules and static assets.

@module express-yui/lib/origin
**/

'use strict';

var libpath = require('path'),
    utils = require('./utils'),
    debug = require('debug')('express:yui:origin');

/**
Facilitates the configuration of YUI Core modules and other
groups to be served from the express app in a form of origin server.

    var express = require('express'),
        expyui = require('express-yui'),
        app = express();

    expyui.extend(app);
    // registering a group called `app` based on a folder generated by `shifter` or any similar tool.
    app.yui.registerGroup('app', '/path/to/build/groupName', 'loader-app');

    app.use(expyui.expose());
    app.use(expyui.static('/path/to/build'));

In the example above, the group/bundle should be built into the `/path/to/build` prior
to registering the new group. This process is normaly carry on by the `locator` instance,
or using `shifter` directly. But once `express-yui` receive the information about the
new group, it will automatically provision that new group into the client side by
using the `loader-<groupName>` module as the meta module.

@class origin
@static
@uses utils, *path
@extensionfor express-yui/lib/yui
*/
module.exports = {

    /**
    Set YUI Core Modules from the same origin as to where the application
    is hosted.

    This is not recommended for production and instead you should use a
    `cdn` to server the build folder, but it is a very useful feature for
    development. Here is an example on how to use it:

        app.yui.setCoreFromAppOrigin();

    @method setCoreFromAppOrigin
    @public
    @param {Object} loaderConfig optional loader configuration for the core
    @chainable
    **/
    setCoreFromAppOrigin: function (loaderConfig) {

        var groupDefaultBase = this._app.get('yui default base'),
            groupDefaultRoot = this._app.get('yui default root'),
            comboConfig = this._app.get('yui combo config'),
            config = this.config(),
            yuiDir = 'yui-' + this.version;

        utils.extend(config, comboConfig, {
            base: utils.joinURLFolder(groupDefaultBase, yuiDir),
            root: utils.joinURLFolder(groupDefaultRoot, yuiDir)
        }, loaderConfig);

        return this;

    },

    /**
    Set a custom loader configuration for the group.

    Here is an example of how to use it.

        app.yui.applyGroupConfig('app', {
            maxURLLength: 2048,
            comboBase: "/combo?"
            comboSep: "&"
        });

    @method applyGroupConfig
    @public
    @param {String} groupName the name of the group used by loader.
    @param {Object} loaderConfig custom loader configuration
    for the group.
    @chainable
    **/
    applyGroupConfig: function (groupName, loaderConfig) {

        var config = this.config();

        loaderConfig = loaderConfig || {};
        // setting up the group base config if needed
        config.groups = config.groups || {};
        config.groups[groupName] = config.groups[groupName] || {};

        config.groups[groupName] = utils.extend(config.groups[groupName], loaderConfig);

        return this;

    },

    /**
    Register a group by defining the group configuration for the loader.
    Groups can be served from origin app or from CDN by calling `applyGroupConfig`
    or by setting `yui default base`, `yui default root` and `yui combo config` thru
    `app.set()`.

    Here is an example on how to use it, assuming that the YUI metadata are
    located in the `build` directory under the app root.

        app.yui.registerGroup('app', __dirname + '/build', 'loader-app');

    @method registerGroup
    @public
    @param {String} groupName the name of the group used by loader.
    @param {String} groupRoot filesystem path for the group. This will be used to
    analyze all modules in the group.
    @param {String} metaModuleName optional module name to denotate the yui module that holds
    the metas for the group. Default value: `loader-<groupName>`
    @chainable
    **/
    registerGroup: function (groupName, groupRoot, metaModuleName) {

        var groupDefaultBase = this._app.get('yui default base'),
            groupDefaultRoot = this._app.get('yui default root'),
            comboConfig = this._app.get('yui combo config'),
            groupConfig,
            config = this.config(),
            groupDir = libpath.basename(groupRoot);

        metaModuleName = metaModuleName || 'loader-' + groupName;

        debug('Registering group "%s" and provisioning it for the ' +
              'client side with meta module "%s"', groupName, metaModuleName);

        // defining the meta module as a client side module if needed.
        // this helps to use `express-yui` without calling `registerBundle()`
        if (!this._clientModules[metaModuleName]) {
            this._clientModules[metaModuleName] = {
                group: groupName
            };
        }

        config.groups = config.groups || {};

        // setting up the default group config
        groupConfig = config.groups[groupName] = utils.extend({
            base: utils.joinURLFolder(groupDefaultBase, groupDir),
            root: utils.joinURLFolder(groupDefaultRoot, groupDir),
            // inherit combine
            combine: config.hasOwnProperty('combine') ? config.combine : true,
            // inherit filter
            filter: config.hasOwnProperty('filter') ? config.filter : 'min'
        }, comboConfig, config.groups[groupName] || {});

        // add the meta module into the core structure
        // to make sure it gets attached to Y upfront
        this.addModuleToSeed(metaModuleName);

        return this;

    }

};