-
-
Save briancavalier/1986090 to your computer and use it in GitHub Desktop.
Builder plugin for r.js to build Wire.js files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @license Copyright (c) 2010-2011 Brian Cavalier | |
* LICENSE: see the LICENSE.txt file. If file is missing, this file is subject | |
* to the MIT License at: http://www.opensource.org/licenses/mit-license.php. | |
*/ | |
/** | |
* Builder plugin for r.js | |
*/ | |
define([ 'wire/base' ], function() { | |
var defaultModuleRegex, defaultSpecRegex, fs; | |
// default dependency regex | |
defaultModuleRegex = /\.(module|create)$/; | |
defaultSpecRegex = /\.(wire|spec)$/; | |
function isStrictlyObject( obj ) { | |
return obj === Object(obj); | |
} | |
function isArray( obj ) { | |
return Object.prototype.toString.call( obj ) == '[object Array]'; | |
} | |
// Using special require.nodeRequire, something added by r.js. | |
fs = require.nodeRequire('fs'); | |
function fetchText(path, callback) { | |
callback(fs.readFileSync(path, 'utf8')); | |
} | |
function analyze(name, req, load, config) { | |
// Track all modules seen in wire spec, so we only include them once | |
var modules, seenModules, specs, spec, i, childSpecRegex, moduleRegex; | |
moduleRegex = defaultModuleRegex; | |
childSpecRegex = defaultSpecRegex; | |
// Initalise | |
seenModules = {}; | |
modules = []; | |
// Get config values | |
if(config) { | |
if(config.moduleRegex) moduleRegex = new RegExp(config.moduleRegex); | |
if(config.childSpecRegex) childSpecRegex = new RegExp(config.childSpecRegex); | |
} | |
function addAbsoluteDep(absoluteId) { | |
// Only add the moduleId if we haven't already | |
if (absoluteId in seenModules) return; | |
seenModules[absoluteId] = 1; | |
modules.push(absoluteId); | |
} | |
function addDependency(moduleId) { | |
addAbsoluteDep(moduleId); | |
} | |
function addChildSpec(specId) { | |
addAbsoluteDep('wire' + '!' + specId); | |
} | |
function scanObj(obj, path) { | |
// Scan all keys. This might be the spec itself, or any sub-object-literal | |
// in the spec. | |
for (var name in obj) { | |
scanItem(obj[name], path ? ([path, name].join('.')) : name); | |
} | |
} | |
function scanItem(it, path) { | |
// Determine the kind of thing we're looking at | |
// 1. If it's a string, and the key is module or create, then assume it | |
// is a moduleId, and add it as a dependency. | |
// 2. If it's an object or an array, scan it recursively | |
if (typeof it === 'string') { | |
// If it's a regular module, add it as a dependency | |
// If it's child spec, add it as a wire! dependency | |
if (isDep(path)) { | |
addDependency(it); | |
} else if (isWireDep(path)) { | |
addChildSpec(it); | |
} | |
} | |
if (isDep(path) && typeof it === 'string') { | |
// Get module def | |
addDependency(it); | |
} else if (isStrictlyObject(it)) { | |
// Descend into subscope | |
scanObj(it, path); | |
} else if (isArray(it)) { | |
// Descend into array | |
var arrayPath = path + '[]'; | |
for (var i = 0, len = it.length; i < len; i++) { | |
scanItem(it[i], arrayPath); | |
} | |
} | |
} | |
function isWireDep(path) { | |
return childSpecRegex && childSpecRegex.test(path); | |
} | |
function isDep(path) { | |
return moduleRegex.test(path); | |
} | |
// Read in our spec file | |
fetchText( req.toUrl( name ), function( text ) { | |
// Load our spec to as module from the text, then grab it via require | |
load.fromText( 'wire/builder/' + name, text ); | |
req( [ 'wire/builder/' + name ], function( spec_obj ) { | |
// Scan for dependency | |
scanObj( spec_obj ); | |
// Add itself as its last dependency | |
addDependency( name ); | |
// Load our dependences as an AMD module so they are called correctly | |
// This will always have at least one module to call (the spec) | |
load.fromText( 'wire/builder/deps/' + name, 'define( ["' + modules.join( '","' ) + '"], {} );' ); | |
// tell r.js that we are finished working | |
load( spec_obj ); | |
} ); | |
} ); | |
} | |
return { | |
load: analyze | |
}; | |
}); |
Hey Patrick,
The r.js build plugin was created by @pieter-vanderwerff. We're planning to integrate it into a future wire release (probably later this month), but I haven't used it with r.js to do a build, so I don't know enough yet to be much help. However, I do know that Pieter has been using it in production. I don't know what his time is like, but he may be able to help get you started.
Good luck!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Brian,
I'm trying to work with wire.js and r.js to build my project, Can you provide me any examples for instance, here's my main.js file:
(function() {
require.config({
baseUrl: "src",
paths: {
wire: "libs/wire",
"wire/domReady": "domReady",
when: "libs/wire/support/when/when",
aop: "libs/wire/support/aop/aop",
jquery: "libs/jquery/jquery-1.7.1.min",
underscore: "libs/underscore/underscore-1.3.3",
restDelegate: "delegates/restDelegate",
backbone: "libs/backbone/backbone-amd",
omniture: "libs/omniture/s_code",
views: "presentation/views",
utils: "utils",
templates: "presentation/templates/desktop"
},
waitSeconds: 400,
packages: [
{
name: "when",
location: "libs/wire/support/when",
path: "wire/support/when",
lib: ".",
main: "when"
}
],
plugins: [
{
module: "libs/wire/debug",
module: "libs/wire/dom"
}
],
priority: ["jquery", "underscore", "backbone"]
});
require(["app"], function(app) {
return require(["wire!applicationContext"]);
});
}).call(this);