UNPKG

express-yui

Version:

Express extension for YUI Applications

265 lines (195 loc) 7.95 kB
/* * 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 */ /** The `express-yui.origin` extension that provides a set of features to mutate the express app into an origin server for yui modules and static assets. @module yui @submodule origin **/ 'use strict'; var libpath = require('path'), utils = require('./utils'), DEFAULT_COMBO_CONFIG = { maxURLLength: 1024, comboBase: "/combo~", comboSep: "~" }; /** The `express-yui.origin` extension that provides some basic configuration that will facilitate the configuration of YUI Core modules and other groups to be served from the express app in a form of origin server. This is not recommended for production and instead you should use the `cdn` module, but it is a very useful feature for development of offline applications. // Creates a new express app. var app = express(); // getting YUI Core modules from the app origin. app.yui.setCoreFromAppOrigin(); // registering a group `app` based on a folder generated by `shifter` module app.yui.registerGroup('app', '/path/to/foo/yui-build'); // getting group `app` from the app origin. app.yui.setGroupFromAppOrigin('app'); // add support for `combine` for core and `app` groups. app.yui.combineGroups(); app.use(yui.static()); @class origin @static @uses utils, *path @extensionfor yui */ module.exports = { /** Set YUI Core Modules from the same origin as to where the application is hosted. Here is an example on how to use it: app.yui.setCoreFromAppOrigin({}); @method setCoreFromAppOrigin @public @param {Object} loaderConfig @chainable **/ setCoreFromAppOrigin: function (loaderConfig) { var prefix = this._app.set('yui static prefix') || "/", config = this.config(); loaderConfig = loaderConfig || {}; // fixed base and root for this group loaderConfig.base = prefix + "yui/"; loaderConfig.root = "/yui/"; loaderConfig.local = true; loaderConfig = utils.extend(config, DEFAULT_COMBO_CONFIG, loaderConfig); return this; }, /** Set a registered group from the app origin server as to where the application is hosted. Here is an example of how to use it. app.yui.setGroupFromAppOrigin('app', { }, { }); @method setGroupFromAppOrigin @public @param {String} groupName the name of the group used by loader. @param {Object} loaderConfig The custom loader configuration for the group. @param {number} loaderConfig.maxURLLength default to `1024` @param {string} loaderConfig.comboBase default to `"/combo~"` @param {string} loaderConfig.comboSep default to `"~"` @chainable **/ setGroupFromAppOrigin: function (groupName, loaderConfig) { var prefix = this._app.set('yui static prefix') || "/", config = this.config(), folderPath = groupName && this._groupFolderMap && this._groupFolderMap[groupName]; if (!folderPath || !config.groups || !config.groups[groupName]) { throw new Error("Unknown group name [" + groupName + '], ' + "you should register the group by calling `registerGroup()` method."); } loaderConfig = loaderConfig || {}; loaderConfig.base = prefix + groupName + "/"; loaderConfig.root = "/" + groupName + "/"; loaderConfig.local = true; loaderConfig = utils.extend(config.groups[groupName], DEFAULT_COMBO_CONFIG, loaderConfig); return this; }, /** Register a group and its modules by analyzing the meta file and defining the group configuration for the loader. Groups can be served from origin app or from CDN by calling `setGroupFromAppOrigin` or `setGroupFromCDN`. 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'); @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} metaFile optional filesystem path for the yui module that holds the metas for the group. Default value: `<groupRoot>/<groupName>/<groupName>.js` @chainable **/ registerGroup: function (groupName, groupRoot, metaFile) { var group, groupConfig, config; metaFile = metaFile || libpath.join(groupRoot, groupName, groupName + '.js'); // collect the group information from the meta file group = this.getGroupConfig(metaFile); if (!group) { throw new Error("Invalid meta file [" + metaFile + "], " + "it contains no group."); } if (groupName !== group.groupName) { throw new Error("Mismatch between the groupName [" + groupName + "] and the group registered in [" + metaFile + "]."); } config = this.config(); config.groups = config.groups || {}; config.groups[groupName] = groupConfig = config.groups[groupName] || {}; // inherit combine if needed if (!groupConfig.hasOwnProperty('combine')) { groupConfig.combine = config.combine; } // inherit filter if needed if (!groupConfig.hasOwnProperty('filter')) { groupConfig.filter = config.filter; } // storing the root path to the group in case we // need it later to server the group from origin server this._groupFolderMap = this._groupFolderMap || {}; this._groupFolderMap[groupName] = groupRoot; // add the meta module into the core structure // to make sure it gets attached to Y upfront this.addModuleToSeed(group.moduleName, groupName); return this; }, /** Combine group and core modules if they loader configuration matches the values of `loaderConfig.comboBase` and `loaderConfig.comboSep`. The default configuration for the combo is: { maxURLLength: 1024, comboBase: "/combo~", comboSep: "~" } Here is an example of how to use it: app.yui.combineGroups(); Note: this method should be called after defining the settings for all groups and core modules. @method combineGroups @public @param {Object} loaderConfig The base loader configuration for the groups to be combined. @param {Number} loaderConfig.maxURLLength default to `1024` @param {String} loaderConfig.comboBase default to `"/combo~"` @param {String} loaderConfig.comboSep default to `"~"` @chainable **/ combineGroups: function (loaderConfig) { var config = this.config(), groups = config.groups || {}, group; // getting options ready, mixing it with default values loaderConfig = utils.extend({}, DEFAULT_COMBO_CONFIG, (loaderConfig || {})); function fnTestGroup(g) { return g.comboBase === loaderConfig.comboBase && g.comboSep === loaderConfig.comboSep && g.combine !== false && g.root; } // forcing combine for yui if (fnTestGroup(config)) { config.combine = true; } // forcing combine for group that can work with combo for (group in groups) { if (groups.hasOwnProperty(group) && fnTestGroup(groups[group])) { groups[group].combine = true; } } return this; } };