Permalink
Browse files

Ch-ch-ch-changes

  • Loading branch information...
1 parent 9a89547 commit d2d6b89a8a6f72d19ee7bb8fc1c9a69cf2c0d30f @shinypb shinypb committed Dec 20, 2011
Showing with 90 additions and 27 deletions.
  1. +61 −9 src/loadbuilder/asset.js
  2. +18 −7 src/loadbuilder/builder.js
  3. +11 −11 test/asset.js
View
@@ -6,11 +6,13 @@ var util = require('./util'),
uglify = require("uglify-js");
var USING = [ 'call', [ 'name', 'using' ], null ];
+var ARRAY_ARG = [ 'array', null ];
var STRING_ARG = [ 'string', null ];
var PROVIDE = [ 'call', [ 'name', 'provide' ], null ];
var REQUIRE = [ 'call', [ 'name', 'require' ], [ [ 'string', null] ] ];
var dependencyCache = {};
+var dependencyCacheLastUpdate = {};
function Script(id) {
this.id = id;
@@ -21,6 +23,12 @@ util.extend(Script.prototype, {
var usings, dependencies = [];
+ if(dependencyCache[this.id]) {
+ // Make sure it's not out of date
+ console.log('oodate?');
+ console.log(dependencyCache[this.id]);
+ }
+
if (!dependencyCache[this.id]) {
usings = analyzer.analyze(USING, this.fromFile());
@@ -33,11 +41,23 @@ util.extend(Script.prototype, {
if (m = analyzer.match(STRING_ARG, arg)) {
dep = this.builder.matchAsset(m[0]);
dependencies = dependencies.concat(dep);
+ } else if(m = analyzer.match(ARRAY_ARG, arg)) {
+ arg[1].forEach(function(arg) {
+ // FIXME: duplicate code; un-nest this stuff
+ // nesty :(
+ var dep, m;
+
+ if (m = analyzer.match(STRING_ARG, arg)) {
+ dep = this.builder.matchAsset(m[0]);
+ dependencies = dependencies.concat(dep);
+ }
+ }, this);
}
}, this);
}, this);
dependencyCache[this.id] = dependencies;
+ dependencyCacheLastUpdate[this.id] = new Date();
}
return dependencyCache[this.id];
@@ -58,9 +78,26 @@ util.extend(Script.prototype, {
return this.deferWrapper(this._source);
},
+ preProcess: function(data) {
+ /**
+ * Expands #define statements inside of JavaScript comments into variable declarations.
+ *
+ * For example, this...
+ * #define foo bar
+ *
+ * ...will be replaced with this:
+ * var foo = 'bar';
+ */
+ return data.replace(/\/\*\s*#define\s+([^\s]+)\s+((\n|.)+?)\*\//g, function(entireBlock, name, value) {
+ value = value.replace(/\n/g, "\\n\\\n");
+ value = value.replace(/"/g, '\\"');
+ return 'var ' + name + ' = "' + value + '";';
+ });
+ },
fromFile: function() {
+ console.log('from file', this.id);
if (!this._fromFile) {
- this._fromFile = fs.readFileSync(this.fullPath(), 'utf8');
+ this._fromFile = this.preProcess(fs.readFileSync(this.fullPath(), 'utf8'));
}
return this._fromFile;
@@ -96,6 +133,10 @@ Module.cjsMemo = {};
util.extend(Module.prototype, {
fullPath: function() {
+ if(this.id.indexOf('bluejs') === 0) {
+ // FIXME: stop special casing bluejs and understand how it currently works in Monorail
+ return this.builder.modPath('../../' + this.id + '.js');
+ }
return this.builder.modPath(this.id + '.js');
},
toSource: function() {
@@ -105,27 +146,27 @@ util.extend(Module.prototype, {
} else {
this._source = this.addId(this.fromFile());
}
+ } else {
+ console.log("Already had source");
}
return this._source;
},
isCJS: function() {
if (typeof this._isCJS == 'undefined') {
+ // FIXME: no memoization in Loadbuilder, please.
var fileInfo = fs.statSync(this.fullPath());
var cjsMemoKey = fileInfo.mtime + '_' + this.fullPath();
if(typeof(Module.cjsMemo[cjsMemoKey]) !== 'undefined') {
- console.log('memo', cjsMemoKey);
this._isCJS = Module.cjsMemo[cjsMemoKey];
- } else { console.log('miss', cjsMemoKey);
- this._isCJS = Module.cjsMemo[cjsMemoKey] = !analyzer.analyze(PROVIDE, this.fromFile());
- console.log(Module.cjsMemo);
+ } else {
+ this._isCJS = Module.cjsMemo[cjsMemoKey] = !analyzer.analyze(PROVIDE, this.fromFile()).length;
}
}
return this._isCJS;
},
amdWrappedSource: function() {
- console.log(this.dependencies());
var deps = ['require', 'exports'].concat(this.dependencies().map(function(d) { return d.id; })),
preamble = "(function() {\nvar module=define(" + JSON.stringify(this.id) + "," +
JSON.stringify(deps) + ",function(require, exports) {\n",
@@ -135,8 +176,14 @@ util.extend(Module.prototype, {
},
dependencies: function() {
- if (this.isCJS()) return this.dependenciesFromRequire();
- else return Script.prototype.dependencies.call(this);
+ if(!this._deps) {
+ if (this.isCJS()) {
+ this._deps = this.dependenciesFromRequire();
+ } else {
+ this._deps = Script.prototype.dependencies.call(this);
+ }
+ }
+ return this._deps;
},
dependenciesFromRequire: function() {
var requires;
@@ -156,13 +203,18 @@ util.extend(Module.prototype, {
provides = analyzer.analyze(PROVIDE, tree),
provide;
- if (provides.length == 1) {
+ if (provides.length > 0) {
provide = provides[0];
// TODO make this nice - maybe have a transform function?
if (analyzer.match(STRING_ARG, provide.values[0][0]) == null) {
provide.parent[provide.index][2].unshift(['string', this.id]);
+ } else {
+ console.log("string thing is null");
}
+ } else {
+ console.log("provides.length is zero", provides.length);
+ console.log(JSON.stringify(provides));
}
return uglify.uglify.gen_code(tree, { beautify: true });
View
@@ -8,12 +8,17 @@ function collect(excluded, assets, includeDependencies) {
var collected = [];
assets.forEach(function(asset) {
+ if(!asset) {
+ console.warn('Undefined asset in assets list');
+ console.log(new Error().stack);
+ return;
+ }
var deps = [];
-
if (excluded.indexOf(asset.id) < 0) {
if (includeDependencies) {
deps = asset.dependencies();
}
+ excluded = excluded.concat([asset.id]);
collected = collected.concat(
collect(excluded, deps, includeDependencies)
@@ -44,7 +49,8 @@ function Builder(options) {
util.extend(this.options, Builder.default_options);
util.extend(this.options, options || {});
this.assets = [];
- this.excludes = [];
+ this.excludes = this.options.excludes || [];
+ this.matchers = [];
}
Builder.default_options = {
@@ -81,12 +87,15 @@ util.extend(Builder.prototype, {
modPath: function(id) {
return path.join(this.options.docroot, this.options.path, id);
},
+ addMatcher: function(regex, factory) {
+ this.matchers.push([regex, factory]);
+ },
matchAsset: function(id) {
var m, dep, asset;
-
- for (var i=0, matcher; matcher = builder.matchers[i]; i++) {
+ var allMatchers = this.matchers.concat(builder.matchers);
+ for (var i=0, matcher; matcher = allMatchers[i]; i++) {
var regex = matcher[0], factory = matcher[1];
- if (m = id.match(regex)) {
+ if (this.excludes.indexOf(id) < 0 && (m = id.match(regex))) {
asset = factory(id);
asset.builder = this;
return asset;
@@ -174,11 +183,13 @@ builder.matchers.add = function(regex, factory) {
this.unshift([regex, factory]);
}
-builder.matchers.add(/^[a-zA-Z0-9_\-\/]+$/, function(id) {
+asset.Module.regexp = /^[a-zA-Z0-9_\-\/]+$/;
+builder.matchers.add(asset.Module.regexp, function(id) {
return new asset.Module(id);
})
-builder.matchers.add(/.js$/, function(id) {
+asset.Script.regexp = /.js$/;
+builder.matchers.add(asset.Script.regexp, function(id) {
return new asset.Script(id);
})
View
@@ -30,7 +30,7 @@ module.exports = {
var a = new asset.Module('anon');
a.builder = builder({
docroot: __dirname,
- path: __dirname + '/modules'
+ path: '/modules'
});
assert.equal('provide("anon", function(exports) {\n exports("hi");\n});', a.toSource());
@@ -39,7 +39,7 @@ module.exports = {
var a = new asset.Module('named');
a.builder = builder({
docroot: __dirname,
- path: __dirname + '/modules'
+ path: '/modules'
});
assert.equal('provide("shindig", function(exports) {\n exports("hi");\n});', a.toSource());
@@ -48,29 +48,29 @@ module.exports = {
var a = new asset.Module('has_dep');
a.builder = builder({
docroot: __dirname,
- path: __dirname + '/modules'
+ path: '/modules'
});
assert.equal('anon', a.dependencies()[0].id);
},
- testShouldFindDependenciesForCommonJSModule: function() {
- var a = new asset.CommonJSModule('common');
+ testShouldFindDependenciesForModule: function() {
+ var a = new asset.Module('common');
a.builder = builder({
docroot: __dirname,
- path: __dirname + '/modules'
+ path: '/modules'
});
assert.equal('anon', a.dependencies()[0].id);
},
- testShouldWrapCommonJSModule: function() {
- var a = new asset.CommonJSModule('common');
+ testShouldWrapModule: function() {
+ var a = new asset.Module('common');
a.builder = builder({
docroot: __dirname,
- path: __dirname + '/modules'
+ path: '/modules'
});
- assert.equal('(function() {\nvar module=define("common",["require","anon"],' +
- 'function(require) {\nvar a = require("anon");\n});\n})();', a.toSource());
+ assert.equal('(function() {\nvar module=define("common",["require","exports","anon"],' +
+ 'function(require, exports) {\nvar a = require("anon");\n});\n})();', a.toSource());
}
}

0 comments on commit d2d6b89

Please sign in to comment.