Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

v.0.3alpha15 - early release

- setting main automagically
- improved done() handling
- r.js issues - logLevels when debugLevel > 90
- l.prettify, solved Bundle getFilesFactory,
- Gruntfile.coffee cleanup
  • Loading branch information...
commit 7866cdb047d02dd267f833fc07a45e27dd8b1921 1 parent ca50496
@anodynos authored
Showing with 8,125 additions and 193 deletions.
  1. +1 −3 .gitignore
  2. +0 −5 .npmignore
  3. +8 −59 Gruntfile.coffee
  4. +110 −0 build/code/DependenciesReporter.js
  5. +211 −0 build/code/Dependency.js
  6. +433 −0 build/code/NodeRequirer.js
  7. +207 −0 build/code/config/uRequireConfigMasterDefaults.js
  8. +300 −0 build/code/moduleManipulation/ModuleManipulator.js
  9. +54 −0 build/code/moduleManipulation/seekr.js
  10. +97 −0 build/code/paths/pathRelative.js
  11. +23 −0 build/code/paths/resolvePathToFromModuleRoot.js
  12. +77 −0 build/code/paths/upath.js
  13. +117 −0 build/code/process/Build.js
  14. +473 −0 build/code/process/Bundle.js
  15. +119 −0 build/code/process/BundleBase.js
  16. +200 −0 build/code/process/BundleBuilder.js
  17. +381 −0 build/code/process/UModule.js
  18. +92 −0 build/code/templates/AlmondOptimizationTemplate.js
  19. +156 −0 build/code/templates/ModuleGeneratorTemplates.js
  20. +62 −0 build/code/urequire.js
  21. +87 −0 build/code/urequireCmd.js
  22. +93 −0 build/code/utils/Logger.js
  23. +33 −0 build/code/utils/getFiles.js
  24. +110 −0 build/code/utils/uBerscoreShortcuts.js
  25. +110 −0 build/js/code/DependenciesReporter.js
  26. +211 −0 build/js/code/Dependency.js
  27. +433 −0 build/js/code/NodeRequirer.js
  28. +202 −0 build/js/code/config/uRequireConfigMasterDefaults.js
  29. +300 −0 build/js/code/moduleManipulation/ModuleManipulator.js
  30. +54 −0 build/js/code/moduleManipulation/seekr.js
  31. +97 −0 build/js/code/paths/pathRelative.js
  32. +23 −0 build/js/code/paths/resolvePathToFromModuleRoot.js
  33. +77 −0 build/js/code/paths/upath.js
  34. +115 −0 build/js/code/process/Build.js
  35. +431 −0 build/js/code/process/Bundle.js
  36. +119 −0 build/js/code/process/BundleBase.js
  37. +167 −0 build/js/code/process/BundleBuilder.js
  38. +381 −0 build/js/code/process/UModule.js
  39. +92 −0 build/js/code/templates/AlmondOptimizationTemplate.js
  40. +156 −0 build/js/code/templates/ModuleGeneratorTemplates.js
  41. +46 −0 build/js/code/urequire.js
  42. +69 −0 build/js/code/urequireCmd.js
  43. +85 −0 build/js/code/utils/Logger.js
  44. +33 −0 build/js/code/utils/getFiles.js
  45. +110 −0 build/js/code/utils/uBerscoreShortcuts.js
  46. +233 −0 build/js/spec/Dependency-spec.js
  47. +107 −0 build/js/spec/ModuleManipulator-spec.js
  48. +96 −0 build/js/spec/NodeRequirer-spec.js
  49. +110 −0 build/js/spec/pathRelative-spec.js
  50. +36 −0 build/js/spec/resolvePathToFromModuleRoot-spec.js
  51. +233 −0 build/spec/Dependency-spec.js
  52. +107 −0 build/spec/ModuleManipulator-spec.js
  53. +96 −0 build/spec/NodeRequirer-spec.js
  54. +110 −0 build/spec/pathRelative-spec.js
  55. +13 −0 build/spec/requirejs.config.json
  56. +36 −0 build/spec/resolvePathToFromModuleRoot-spec.js
  57. +4 −4 package.json
  58. +22 −1 readme.md
  59. +3 −2 source/code/NodeRequirer.coffee
  60. +3 −2 source/code/config/uRequireConfigMasterDefaults.coffee
  61. +1 −0  source/code/process/Build.coffee
  62. +79 −63 source/code/process/Bundle.coffee
  63. +26 −22 source/code/process/BundleBuilder.coffee
  64. +24 −8 source/code/process/UModule.coffee
  65. +7 −1 source/code/urequire.coffee
  66. +9 −8 source/code/urequireCmd.coffee
  67. +6 −2 source/code/utils/Logger.coffee
  68. +9 −13 todos.txt
View
4 .gitignore
@@ -1,4 +1,2 @@
/.idea/
-/node_modules/
-/build/
-/doc/
+/node_modules/
View
5 .npmignore
@@ -1,12 +1,7 @@
/.idea/
/node_modules/
-/libs/
/source/
/grunt*
-/samples
/build/spec/
-/build/examples/
-/package.coffee
/.npmignore
/*.bat
-/*.sh
View
67 Gruntfile.coffee
@@ -2,8 +2,6 @@ _fs = require 'fs'
_ = require 'lodash'
_B = require 'uberscore'
-isWin32 = process.platform is "win32"
-
gruntFunction = (grunt) ->
sourceDir = "source/code"
@@ -13,8 +11,6 @@ gruntFunction = (grunt) ->
pkg = JSON.parse _fs.readFileSync './package.json', 'utf-8'
- globalBuildCode = "c:/Program Files/nodejs/node_modules/urequire/build/code/"
-
gruntConfig =
pkg: "<json:package.json>"
@@ -37,7 +33,6 @@ gruntFunction = (grunt) ->
buildDir: buildDir
sourceSpecDir: sourceSpecDir
buildSpecDir: buildSpecDir
- globalBuildCode: globalBuildCode
shell:
coffee:
@@ -52,19 +47,6 @@ gruntFunction = (grunt) ->
mocha:
command: "mocha #{buildSpecDir} --recursive --bail --reporter spec"
- chmod: # change urequireCmd.js to executable - linux only (?mac?)
- command: switch process.platform
- when "linux" then "chmod +x '#{globalBuildCode}urequireCmd.js'"
- else "" #do nothing
-
- dos2unix: # download from http://sourceforge.net/projects/dos2unix/files/latest/download
- command: switch process.platform
- when "win32" then "dos2unix build/code/urequireCmd.js"
- else "" #do nothing
-
- globalInstall:
- command: "npm install -g"
-
doc:
command: "codo source/code --title 'uRequire #{pkg.version} API documentation' --cautious"
@@ -73,6 +55,13 @@ gruntFunction = (grunt) ->
stdout: true
stderr: true
+ copy:
+ specResources:
+ options: flatten: false
+ files: #copy all ["source/**/*.html", "...txt" ]
+ "<%= options.buildSpecDir %>/":
+ ("#{sourceSpecDir}/**/#{ext}" for ext in [ "*.html", "*.js", "*.txt", "*.json" ])
+
concat:
bin:
src: [
@@ -89,48 +78,12 @@ gruntFunction = (grunt) ->
]
dest:'<%= options.buildDir %>/utils/Logger.js'
- copy:
- specResources:
- options: flatten: false
- files: #copy all ["source/**/*.html", "...txt" ]
- "<%= options.buildSpecDir %>/":
- ("#{sourceSpecDir}/**/#{ext}" for ext in [ "*.html", "*.js", "*.txt", "*.json" ])
-
- if isWin32 then _B.deepExtend gruntConfig,
- copy:
- globalInstallTests:
- files:
- "<%= options.globalBuildCode %>": [ #dest
- "<%= options.buildDir %>/**/*.js" #source
- ]
-
- uRequireExamples_node_modules: #needed by the examples, makeNodeRequire()
- files:
- "../uRequireExamples/node_modules/urequire/build/code/": [ #dest
- "<%= options.buildDir %>/**/*.js" #source
- ]
-
- uBerscore_node_modules: #needed by the examples, makeNodeRequire()
- files:
- "../uBerscore/node_modules/urequire/build/code/": [ #dest
- "<%= options.buildDir %>/**/*.js" #source
- ]
-
- _B.deepExtend gruntConfig,
clean:
build: [
"<%= options.buildDir %>/**/*.*"
"<%= options.buildSpecDir %>/**/*.*"
]
- if isWin32 then _B.deepExtend gruntConfig,
- clean:
- deploy: [
- "c:/Program Files/nodejs/node_modules/urequire/build/code/**/*.*"
- "../uRequireExamples/node_modules/urequire/build/code/"
- "../uBerscore/node_modules/urequire/build/code/"
- ]
-
### shortcuts generation ###
# shortcut to all "shell:cmd"
@@ -139,19 +92,16 @@ gruntFunction = (grunt) ->
# generic shortcuts
grunt.registerTask shortCut, tasks for shortCut, tasks of _B.go {
# basic commands
- "default": "clean build test" + if isWin32 then ' deploy' else ''
+ "default": "clean build test"
"build": "shell:coffee concat"
- "deploy": if isWin32 then "copy dos2unix chmod" else '' #chmod alternative "shell:globalInstall" (slower but more 'correct')
"test": "shell:coffeeSpec copy:specResources mocha"
# generic shortcuts
"cf": "shell:coffee" # there's a 'coffee' task already!
"cfw": "coffeeWatch"
"cl": "clean"
- "cp": "copy" #" todo: all ?
"b": "build"
- "d": "deploy"
"t": "test"
}, fltr: (v)-> !!v #bangbang forces boolean value
@@ -159,7 +109,6 @@ gruntFunction = (grunt) ->
grunt.registerTask shortCut, tasks for shortCut, tasks of {
"alt-c": "cp"
"alt-b": "b"
- "alt-d": "d"
"alt-t": "t"
}
View
110 build/code/DependenciesReporter.js
@@ -0,0 +1,110 @@
+// Generated by CoffeeScript 1.4.0
+var DependenciesReporter, Dependency, _, _B,
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+_ = require('lodash');
+
+_B = require('uberscore');
+
+Dependency = require('./Dependency');
+
+DependenciesReporter = (function() {
+ var DT, dependencyTypesMessages;
+
+ function DependenciesReporter(interestingDepTypes) {
+ this.interestingDepTypes = interestingDepTypes != null ? interestingDepTypes : _.keys(dependencyTypesMessages);
+ this.reportData = {};
+ }
+
+ dependencyTypesMessages = {
+ /* 'problematic' ones
+ */
+
+ untrustedRequireDependencies: {
+ header: "\u001b[31m Untrusted require('') dependencies found:",
+ footer: "They are IGNORED. If evaluated name of the require() isnt in dependency array [..] before require() call, your app WILL HALT and WILL NOT WORK on the web-side (but should be OK on node).\u001b[0m"
+ },
+ untrustedAsyncDependencies: {
+ header: "\u001b[31m Untrusted async require(['']) dependencies found:",
+ footer: "They are IGNORED. If evaluated name of the require([..]) isnt found, you'll get an http error on web, or exception 'module not found' on node.).\u001b[0m"
+ }
+ /* simply interesting :-)
+ */
+
+ };
+
+ DT = Dependency.TYPES;
+
+ _B.okv(dependencyTypesMessages, DT.global, {
+ header: "Global-looking dependencies (not checked in this version):",
+ footer: "They are added as-is."
+ }, DT.notFoundInBundle, {
+ header: "\u001b[31m Bundle-looking dependencies not found in bundle:",
+ footer: "They are added as-is.\u001b[0m"
+ }, DT.external, {
+ header: "External dependencies (not checked in this version):",
+ footer: "They are added as-is."
+ }, DT.webRootMap, {
+ header: "Web root dependencies '/' (not checked in this version):",
+ footer: "They are added as-is."
+ });
+
+ DependenciesReporter.prototype.reportTemplate = function(texts, dependenciesFound) {
+ var dependency, mf, moduleFiles;
+ return "\n" + texts.header + "\n " + ((function() {
+ var _results;
+ _results = [];
+ for (dependency in dependenciesFound) {
+ moduleFiles = dependenciesFound[dependency];
+ _results.push("'" + dependency + "' @ [ " + ((function() {
+ var _i, _len, _results1;
+ _results1 = [];
+ for (_i = 0, _len = moduleFiles.length; _i < _len; _i++) {
+ mf = moduleFiles[_i];
+ _results1.push("\n '" + mf + "'");
+ }
+ return _results1;
+ })()) + "\n ]\n");
+ }
+ return _results;
+ })()) + texts.footer + "\n";
+ };
+
+ DependenciesReporter.prototype.addReportData = function(resolvedDeps, modyle) {
+ var depType, foundModules, resDep, resDeps, _base, _base1, _i, _len;
+ for (depType in resolvedDeps) {
+ resDeps = resolvedDeps[depType];
+ if (!((!_.isEmpty(resDeps)) && __indexOf.call(this.interestingDepTypes, depType) >= 0)) {
+ continue;
+ }
+ (_base = this.reportData)[depType] || (_base[depType] = {});
+ for (_i = 0, _len = resDeps.length; _i < _len; _i++) {
+ resDep = resDeps[_i];
+ foundModules = ((_base1 = this.reportData[depType])[resDep] || (_base1[resDep] = []));
+ if (__indexOf.call(foundModules, modyle) < 0) {
+ foundModules.push(modyle);
+ }
+ }
+ }
+ return null;
+ };
+
+ DependenciesReporter.prototype.getReport = function() {
+ var depType, depTypesMsgs, report;
+ report = "";
+ for (depType in dependencyTypesMessages) {
+ depTypesMsgs = dependencyTypesMessages[depType];
+ if (__indexOf.call(this.interestingDepTypes, depType) >= 0) {
+ if (this.reportData[depType]) {
+ report += this.reportTemplate(depTypesMsgs, this.reportData[depType]);
+ }
+ }
+ }
+ return report;
+ };
+
+ return DependenciesReporter;
+
+})();
+
+module.exports = DependenciesReporter;
View
211 build/code/Dependency.js
@@ -0,0 +1,211 @@
+// Generated by CoffeeScript 1.4.0
+var Dependency, pathRelative, upath, _,
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+_ = require('lodash');
+
+_.mixin((require('underscore.string')).exports());
+
+upath = require('./paths/upath');
+
+pathRelative = require('./paths/pathRelative');
+
+Dependency = (function() {
+ var _this = this;
+
+ Function.prototype.property = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(this.prototype, n, d));
+ }
+ return _results;
+ };
+
+ Function.prototype.staticProperty = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(Dependency.prototype, n, d));
+ }
+ return _results;
+ };
+
+ function Dependency() {
+ this._constructor.apply(this, arguments);
+ }
+
+ Dependency.prototype._constructor = function(dep, moduleFilename, bundleFiles) {
+ var indexOfSep;
+ this.dep = dep;
+ this.moduleFilename = moduleFilename != null ? moduleFilename : '';
+ this.bundleFiles = bundleFiles != null ? bundleFiles : [];
+ this.dep = this.dep.replace(/\\/g, '/');
+ indexOfSep = this.dep.indexOf('!');
+ if (indexOfSep > 0) {
+ this.pluginName = this.dep.slice(0, +(indexOfSep - 1) + 1 || 9e9);
+ }
+ this.resourceName = indexOfSep >= 0 ? this.dep.slice(indexOfSep + 1, +(this.dep.length - 1) + 1 || 9e9) : this.dep;
+ if (upath.extname(this.resourceName)) {
+ this.extname = upath.extname(this.resourceName);
+ return this.resourceName = upath.trimExt(this.resourceName);
+ }
+ };
+
+ Dependency.TYPES = {
+ notFoundInBundle: 'notFoundInBundle',
+ global: 'global',
+ external: 'external',
+ webRootMap: 'webRootMap',
+ bundle: 'bundle'
+ };
+
+ Dependency.property({
+ type: {
+ get: function() {
+ if (this.isGlobal()) {
+ return Dependency.TYPES.global;
+ } else {
+ if (this.isExternal()) {
+ return Dependency.TYPES.external;
+ } else {
+ if (this.isNotFoundInBundle()) {
+ return Dependency.TYPES.notFoundInBundle;
+ } else {
+ if (this.isWebRootMap()) {
+ return Dependency.TYPES.webRootMap;
+ } else {
+ return Dependency.TYPES.bundle;
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+
+ Dependency.prototype.name = function(options) {
+ var _ref, _ref1, _ref2;
+ if (options == null) {
+ options = {};
+ }
+ if ((_ref = options.ext) == null) {
+ options.ext = this.isExternal() || this.isNotFoundInBundle() ? true : false;
+ }
+ if ((_ref1 = options.plugin) == null) {
+ options.plugin = true;
+ }
+ if ((_ref2 = options.relativeType) == null) {
+ options.relativeType = 'file';
+ }
+ return "" + (options.plugin && this.pluginName ? this.pluginName + '!' : '') + (options.relativeType === 'bundle' ? this._bundleRelative() : this._fileRelative()) + (options.ext === false || !this.extname ? '' : this.extname);
+ };
+
+ Dependency.prototype.toString = function() {
+ return this.name();
+ };
+
+ /*
+ Compare this Dependency instance with another, either Dependency or a string representation of another type.
+ It caters for different representations of
+ * bundleRelative / fileRelative
+ * having `.js` extension or not
+
+ @param dep {Dependency | String | .toString} The depedency to compare with this - returns true if
+ */
+
+
+ Dependency.prototype.isEqual = function(dep) {
+ var isSameJSFile;
+ isSameJSFile = function(a, b) {
+ return upath.defaultExt(a, '.js') === upath.defaultExt(b, '.js');
+ };
+ if (_.isFunction(dep.isBundleBoundary && _.isFunction(dep.name))) {
+ return isSameJSFile(dep.name(), this.name());
+ } else {
+ if (!_.isString(dep)) {
+ dep = dep.toString();
+ }
+ }
+ return isSameJSFile(dep, this.name()) || isSameJSFile(dep, this.name({
+ relativeType: 'bundle'
+ }));
+ };
+
+ Dependency.prototype._bundleRelative = function() {
+ if (this.isFileRelative() && this.isBundleBoundary()) {
+ return upath.normalize("" + (upath.dirname(this.moduleFilename)) + "/" + this.resourceName);
+ } else {
+ return this.resourceName;
+ }
+ };
+
+ Dependency.prototype._fileRelative = function() {
+ if (this.moduleFilename && this.isFound()) {
+ return pathRelative("$/" + (upath.dirname(this.moduleFilename)), "$/" + (this._bundleRelative()), {
+ dot4Current: true
+ });
+ } else {
+ return this.resourceName;
+ }
+ };
+
+ Dependency.prototype.isBundleBoundary = function() {
+ if (this.isWebRootMap() || (!this.moduleFilename)) {
+ return false;
+ } else {
+ return !!pathRelative("$/" + this.moduleFilename + "/../../" + this.resourceName, "$");
+ }
+ };
+
+ Dependency.prototype.isFileRelative = function() {
+ return this.resourceName[0] === '.';
+ };
+
+ Dependency.prototype.isRelative = function() {
+ return this.resourceName.indexOf('/') >= 0 && !this.isWebRootMap();
+ };
+
+ Dependency.prototype.isWebRootMap = function() {
+ return this.resourceName[0] === '/';
+ };
+
+ Dependency.prototype.isGlobal = function() {
+ return !this.isWebRootMap() && !this.isRelative() && !this.isFound();
+ };
+
+ /* external-looking deps, like '../../../some/external/lib'
+ */
+
+
+ Dependency.prototype.isExternal = function() {
+ return !(this.isBundleBoundary() || this.isWebRootMap());
+ };
+
+ /* seem to belong to bundle, but not found, like '../myLib'
+ */
+
+
+ Dependency.prototype.isNotFoundInBundle = function() {
+ return this.isBundleBoundary() && !(this.isFound() || this.isGlobal());
+ };
+
+ Dependency.prototype.isFound = function() {
+ var ke, knownExtensions, _i, _len, _ref;
+ knownExtensions = ['.js', '.coffee'];
+ for (_i = 0, _len = knownExtensions.length; _i < _len; _i++) {
+ ke = knownExtensions[_i];
+ if (_ref = this._bundleRelative() + ke, __indexOf.call(this.bundleFiles, _ref) >= 0) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ return Dependency;
+
+}).call(this);
+
+module.exports = Dependency;
View
433 build/code/NodeRequirer.js
@@ -0,0 +1,433 @@
+// Generated by CoffeeScript 1.4.0
+var BundleBase, Dependency, Logger, NodeRequirer, l, pathRelative, upath, _, _fs,
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+_ = require('lodash');
+
+_.mixin((require('underscore.string')).exports());
+
+_fs = require('fs');
+
+upath = require('./paths/upath');
+
+pathRelative = require('./paths/pathRelative');
+
+Dependency = require('./Dependency');
+
+Logger = require('./utils/Logger');
+
+l = new Logger('NodeRequirer', 0);
+
+BundleBase = require('./process/BundleBase');
+
+/*
+The `nodejs`'s require facility.
+
+An instance of `NodeRequirer` is created for each UMD module, when running on node. Its purpose is to resolve and load modules, synchronoysly or asynchronoysly, depending on how it was called:
+
+ * sync (blocking): when call was made the nodejs way `require('dependency')` in which case the module is simply loaded & returned.
+
+ * async (immediatelly returning): when called the AMD/requirejs way `require(['dep1', 'dep2'], function(dep1, dep2) {})` in which case the callback function is called, when all modules/dependencies have been loaded asynchronously.
+
+@note: it used to mimic the inconsistent RequireJS 2.0.x behaviour on the `require([..],->`, where if all deps are loaded before, then the call is SYNCHRONOUS :-(. It is now reverted to the [always asynch 2.1.x behaviour](https://github.com/jrburke/requirejs/wiki/Upgrading-to-RequireJS-2.1#wiki-breaking-async)
+
+@author Agelos Pikoulas
+*/
+
+
+NodeRequirer = (function(_super) {
+ var _this = this;
+
+ __extends(NodeRequirer, _super);
+
+ Function.prototype.property = function(props) {
+ var descr, name, _results;
+ _results = [];
+ for (name in props) {
+ descr = props[name];
+ _results.push(Object.defineProperty(this.prototype, name, descr));
+ }
+ return _results;
+ };
+
+ Function.prototype.staticProperty = function(props) {
+ var descr, name, _results;
+ _results = [];
+ for (name in props) {
+ descr = props[name];
+ _results.push(Object.defineProperty(NodeRequirer.prototype, name, descr));
+ }
+ return _results;
+ };
+
+ /*
+ YADC wants can't grab real 'constructor'
+ */
+
+
+ function NodeRequirer() {
+ this.require = __bind(this.require, this);
+
+ this.loadModule = __bind(this.loadModule, this);
+ this._constructor.apply(this, arguments);
+ }
+
+ /*
+ Create a NodeRequirer instance, passing paths resolution information.
+
+ @param {String} modyle `module` name of current UMD module (that calls 'require'). Relative to bundle, eg 'models/Person', as hardcoded in generated uRequire UMD.
+ @param {String} dirname `__dirname` passed at runtime from the UMD module, poiniting to its self (i.e filename of the .js file).
+ @param {String} webRootMap where '/' is mapped when running on nodejs, as hardcoded in uRequire UMD (relative to bundlePath).
+ */
+
+
+ NodeRequirer.prototype._constructor = function(modyle, dirname, webRootMap) {
+ var baseUrl, oldbundlePath;
+ this.modyle = modyle;
+ this.dirname = dirname;
+ this.webRootMap = webRootMap;
+ this.bundlePath = upath.normalize(this.dirname + '/' + (pathRelative("$/" + (upath.dirname(this.modyle)), "$/")) + '/');
+ l.debug(6, "new NodeRequirer(\n @modyle='" + this.modyle + "'\n @dirname='" + this.dirname + "'\n @webRootMap='" + this.webRootMap + "')\n\n Calculated @bundlePath (from @modyle & @dirname) = " + this.bundlePath);
+ if (this.getRequireJSConfig().baseUrl) {
+ oldbundlePath = this.bundlePath;
+ baseUrl = this.getRequireJSConfig().baseUrl;
+ l.debug(7, "`baseUrl` (from requireJsConfig ) = " + baseUrl);
+ this.bundlePath = upath.normalize((baseUrl[0] === '/' ? this.webRoot : this.bundlePath) + '/' + baseUrl + '/');
+ return l.debug(5, "Final `@bundlePath` (from requireJsConfig.baseUrl & @bundlePath) = " + this.bundlePath);
+ }
+ };
+
+ /*
+ @property {Function}
+ A @staticProperty (class variable) that defaults to node's `require`.
+ It can be swaped with another/mock version (eg by spec tests).
+ */
+
+
+ NodeRequirer.prototype.nodeRequire = void 0;
+
+ NodeRequirer.staticProperty({
+ nodeRequire: {
+ get: function() {
+ return NodeRequirer._nodeRequire || require;
+ },
+ set: function(_nodeRequire) {
+ NodeRequirer._nodeRequire = _nodeRequire;
+ }
+ }
+ });
+
+ NodeRequirer.property({
+ debugInfo: {
+ get: function() {
+ var bundlePathsRjs, bundlePathsRjsConfig, config, di, rjs, rjsConfig, rjsConfigs, rjsLoaded, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
+ di = {
+ bundlePath: this.bundlePath,
+ webRoot: this.webRoot
+ };
+ rjsLoaded = di["requirejsLoaded[@bundlePath]"] = {};
+ _ref = NodeRequirer.prototype.requirejsLoaded;
+ for (bundlePathsRjs in _ref) {
+ rjs = _ref[bundlePathsRjs];
+ rjsConfig = rjsLoaded[bundlePathsRjs] = {};
+ rjsConfig["requirejs._.config.baseUrl"] = (_ref1 = rjs.s) != null ? (_ref2 = _ref1.contexts) != null ? (_ref3 = _ref2._) != null ? _ref3.config.baseUrl : void 0 : void 0 : void 0;
+ rjsConfig["requirejs._.config.paths"] = (_ref4 = rjs.s) != null ? (_ref5 = _ref4.contexts) != null ? (_ref6 = _ref5._) != null ? _ref6.config.paths : void 0 : void 0 : void 0;
+ }
+ rjsConfigs = di["requireJSConfigs[@bundlePath]"] = {};
+ _ref7 = NodeRequirer.prototype.requireJSConfigs;
+ for (bundlePathsRjsConfig in _ref7) {
+ config = _ref7[bundlePathsRjsConfig];
+ rjsConfigs[bundlePathsRjsConfig] = config;
+ }
+ return l.prettify(di);
+ }
+ }
+ });
+
+ /*
+ @property {Set<module>}
+ Stores all modules loaded so far. Its `static` i.e a class variable, shared among all instances.
+ */
+
+
+ NodeRequirer.prototype.cachedModules = {};
+
+ /*
+ Load 'requirejs.config.json' for @bundlePath & cache it with @bundlePath as key.
+ @return {RequireJSConfig object} the requireJSConfig for @bundlePath (or {} if 'requirejs.config.json' not found/not valid json)
+ */
+
+
+ NodeRequirer.prototype.getRequireJSConfig = function() {
+ var rjsc, _base, _base1, _name, _ref, _ref1;
+ if ((_ref = (_base = NodeRequirer.prototype).requireJSConfigs) == null) {
+ _base.requireJSConfigs = {};
+ }
+ if (NodeRequirer.prototype.requireJSConfigs[this.bundlePath] === void 0) {
+ try {
+ rjsc = require('fs').readFileSync(this.bundlePath + 'requirejs.config.json', 'utf-8');
+ } catch (error) {
+
+ }
+ if (rjsc) {
+ try {
+ NodeRequirer.prototype.requireJSConfigs[this.bundlePath] = JSON.parse(rjsc);
+ } catch (error) {
+ l.err("urequire: error parsing requirejs.config.json from " + (this.bundlePath + 'requirejs.config.json'));
+ }
+ }
+ if ((_ref1 = (_base1 = NodeRequirer.prototype.requireJSConfigs)[_name = this.bundlePath]) == null) {
+ _base1[_name] = {};
+ }
+ }
+ return NodeRequirer.prototype.requireJSConfigs[this.bundlePath];
+ };
+
+ /*
+ Load the [Requirejs](http://requirejs.org/) system module (as npm installed), & cache for @bundlePath as key.
+
+ Then cache it in static NodeRequirer::requirejsLoaded[@bundlePath], so only one instance
+ is shared among all `NodeRequirer`s for a given @bundlePath. Hence, its created only once,
+ first time it's needed (for each distinct @bundlePath).
+
+ It is configuring rjs with resolved paths, for each of the paths entry in `requirejs.config.json`.
+ Resolved paths are relative to `@bundlePath` (instead of `@dirname`).
+
+ @return {requirejs} The module `RequireJS` for node, configured for this @bundlePath.
+ */
+
+
+ NodeRequirer.prototype.getRequirejs = function() {
+ var pathEntries, pathEntry, pathName, requireJsConf, requirejs, resolvedPath, _base, _base1, _i, _j, _len, _len1, _ref, _ref1, _ref2;
+ if ((_ref = (_base = NodeRequirer.prototype).requirejsLoaded) == null) {
+ _base.requirejsLoaded = {};
+ }
+ if (!NodeRequirer.prototype.requirejsLoaded[this.bundlePath]) {
+ requirejs = this.nodeRequire('requirejs');
+ requireJsConf = {
+ nodeRequire: this.nodeRequire,
+ baseUrl: this.bundlePath
+ };
+ if (this.getRequireJSConfig().paths) {
+ requireJsConf.paths = {};
+ _ref1 = this.getRequireJSConfig().paths;
+ for (pathName in _ref1) {
+ pathEntries = _ref1[pathName];
+ if (!_(pathEntries).isArray()) {
+ pathEntries = [pathEntries];
+ }
+ (_base1 = requireJsConf.paths)[pathName] || (_base1[pathName] = []);
+ for (_i = 0, _len = pathEntries.length; _i < _len; _i++) {
+ pathEntry = pathEntries[_i];
+ _ref2 = this.resolvePaths(new Dependency(pathEntry), this.bundlePath);
+ for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
+ resolvedPath = _ref2[_j];
+ if (!(__indexOf.call(requireJsConf.paths[pathName], resolvedPath) >= 0)) {
+ requireJsConf.paths[pathName].push(resolvedPath);
+ }
+ }
+ }
+ }
+ }
+ requirejs.config(requireJsConf);
+ NodeRequirer.prototype.requirejsLoaded[this.bundlePath] = requirejs;
+ }
+ return NodeRequirer.prototype.requirejsLoaded[this.bundlePath];
+ };
+
+ /*
+ Loads *one* module, synchronously.
+
+ Uses either node's `require` or the synchronous version of `RequireJs`'s.
+ The latter is used for modules that :
+ * either have a plugin (eg `"text!module.txt"`)
+ * or modules that failed to load with node's require: these are assumed to be native AMD, hence and attempt is made to load with RequireJS.
+
+ @note If loading failures occur, it makes more than one attempts to find/load a module (alt paths & node/rjs require), noting loading errors. If all loading attempts fail, **it QUITS with process.exit(1)**.
+
+ @param {Dependency} dep The Dependency to be load.
+ @return {module} loaded module or quits if it fails
+ @todo:2 refactor/simplify
+ */
+
+
+ NodeRequirer.prototype.loadModule = function(dep) {
+ var att, attempts, err1, err2, err3, isCached, loadedModule, modulePath, resolvedPathNo, _i, _len, _modulePath, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
+ attempts = [];
+ isCached = false;
+ loadedModule = null;
+ _ref = this.resolvePaths(dep, this.dirname);
+ for (resolvedPathNo = _i = 0, _len = _ref.length; _i < _len; resolvedPathNo = ++_i) {
+ modulePath = _ref[resolvedPathNo];
+ if (!(!loadedModule)) {
+ continue;
+ }
+ _modulePath = modulePath;
+ if ((loadedModule = this.cachedModules[_modulePath])) {
+ isCached = true;
+ } else {
+ if ((_ref1 = dep.pluginName) === (void 0) || _ref1 === 'node') {
+ l.debug(95, "@nodeRequire '" + _modulePath + "'");
+ attempts.push({
+ modulePath: _modulePath,
+ requireUsed: 'nodeRequire',
+ resolvedPathNo: resolvedPathNo,
+ dependency: {
+ name: dep.name(),
+ type: dep.type
+ }
+ });
+ try {
+ loadedModule = this.nodeRequire(_modulePath);
+ } catch (err) {
+ if (err1 === void 0 || !_(err.toString()).startsWith("Error: Cannot find module")) {
+ err1 = err;
+ }
+ l.debug(35, "FAILED: @nodeRequire '" + _modulePath + "' \n err=\n", err);
+ _.extend(_.last(attempts), {
+ urequireError: "Error loading node or UMD module through nodejs require.",
+ error: {
+ name: err.name,
+ message: err.message,
+ errToString: err.toString(),
+ err: err
+ }
+ });
+ _modulePath = upath.addExt(_modulePath, '.js');
+ if (!dep.isGlobal()) {
+ l.debug(25, "FAILURE caused: @getRequirejs() '" + _modulePath + "'");
+ attempts.push({
+ modulePath: _modulePath,
+ requireUsed: 'RequireJS',
+ resolvedPathNo: resolvedPathNo,
+ dependency: {
+ name: dep.name(),
+ type: dep.type
+ }
+ });
+ try {
+ loadedModule = this.getRequirejs()(_modulePath);
+ } catch (err) {
+ err2 = err;
+ l.debug(35, "FAILED: @getRequirejs() '" + _modulePath + "' \n err=" + err2);
+ _.extend(_.last(attempts), {
+ urequireError: "Error loading module through RequireJS; it previously failed with node's require.",
+ error: {
+ name: err.name,
+ message: err.message,
+ errToString: err.toString(),
+ err: err
+ }
+ });
+ }
+ }
+ }
+ } else {
+ _modulePath = "" + dep.pluginName + "!" + _modulePath;
+ l.debug(25, "PLUGIN caused: @getRequirejs() '" + _modulePath + "'");
+ attempts.push({
+ modulePath: _modulePath,
+ requireUsed: 'RequireJS',
+ resolvedPathNo: resolvedPathNo,
+ dependency: {
+ name: dep.name(),
+ type: dep.type,
+ pluginName: dep.pluginName
+ },
+ pluginPaths: (_ref2 = this.requireJSConfig) != null ? _ref2.paths[dep.pluginName] : void 0,
+ pluginResolvedPaths: (_ref3 = this.requirejs) != null ? (_ref4 = _ref3.s) != null ? (_ref5 = _ref4.contexts) != null ? (_ref6 = _ref5._) != null ? (_ref7 = _ref6.config) != null ? _ref7.paths[dep.pluginName] : void 0 : void 0 : void 0 : void 0 : void 0
+ });
+ try {
+ loadedModule = this.getRequirejs()(_modulePath);
+ } catch (err) {
+ err3 = err;
+ _.extend(_.last(attempts), {
+ urequireError: "Error loading *plugin* module through RequireJS.",
+ error: {
+ name: err.name,
+ message: err.message,
+ errToString: err.toString(),
+ err: err
+ }
+ });
+ }
+ }
+ }
+ }
+ if (!loadedModule) {
+ l.err("\n\n*uRequire " + l.VERSION + "*: failed to load dependency: '" + dep + "' in module '" + this.modyle + "' from " + _modulePath + "\nQuiting with throwing 1st error - Detailed attempts follow:\n" + ((function() {
+ var _j, _len1, _results;
+ _results = [];
+ for (_j = 0, _len1 = attempts.length; _j < _len1; _j++) {
+ att = attempts[_j];
+ _results.push(l.prettify(att));
+ }
+ return _results;
+ })()) + "\n\nDebug info:\n", this.debugInfo);
+ throw err1;
+ } else {
+ l.debug(70, "" + (isCached ? "CACHE-" : '') + "loaded module: '" + (dep.name()) + "'\n from : '" + _modulePath + "' :-)");
+ if (!isCached) {
+ l.debug(50, "debugInfo = \u001b[33m" + this.debugInfo + "\"");
+ }
+ return this.cachedModules[_modulePath] = loadedModule;
+ }
+ };
+
+ /*
+ The actual `require` method, called as synchronous or asynchronous.
+
+ It is the method passed to the *factoryBody* of UMD modules
+ (i.e what you call on your uRequire module when running on node)
+ and the one used to load all deps before entering the module's factoryBody.
+
+ @param { String, Array<String> } strDeps
+ As `String`, its a single dependency to load *synchronously*, eg `"models/person"` or `'text!abc.txt'`
+ As `Array<String>`, its an array of dependencies to load *asynchronously* the AMD/RequireJS way, eg `[ "models/person" or 'text!abc.txt' ]`
+
+ @param {Function} callback The callback function to call when all dependencies are loaded, called asynchronously by default
+ (or synchronously if all dependencies were cached, when it matched RequireJs's 2.0.x behaviour
+ [not needed any more in 2.1.x](https://github.com/jrburke/requirejs/wiki/Upgrading-to-RequireJS-2.1#wiki-breaking-async) )
+ @return {module} module loaded if called *synchronously*, or `undefined` if it was called *asynchronously* (why?)
+ */
+
+
+ NodeRequirer.prototype.require = function(strDeps, callback) {
+ var dep, deps, loadDepsAndCall, strDep, _i, _len,
+ _this = this;
+ if (_(strDeps).isString()) {
+ return this.loadModule(new Dependency(strDeps, this.modyle));
+ } else {
+ if (_(strDeps).isArray()) {
+ deps = [];
+ for (_i = 0, _len = strDeps.length; _i < _len; _i++) {
+ strDep = strDeps[_i];
+ deps.push(dep = new Dependency(strDep, this.modyle));
+ }
+ loadDepsAndCall = function() {
+ var loadedDeps, _j, _len1;
+ loadedDeps = [];
+ for (_j = 0, _len1 = deps.length; _j < _len1; _j++) {
+ dep = deps[_j];
+ loadedDeps.push(_this.loadModule(dep));
+ }
+ if (_(callback).isFunction()) {
+ return callback.apply(null, loadedDeps);
+ }
+ };
+ process.nextTick(function() {
+ return loadDepsAndCall();
+ });
+ }
+ }
+ return void 0;
+ };
+
+ return NodeRequirer;
+
+}).call(this, BundleBase);
+
+module.exports = NodeRequirer;
View
207 build/code/config/uRequireConfigMasterDefaults.js
@@ -0,0 +1,207 @@
+// Generated by CoffeeScript 1.4.0
+var Logger, l, rJSON, uRequireConfig, _, _B, _fs;
+
+_fs = require('fs');
+
+_ = require('lodash');
+
+_B = require('uberscore');
+
+Logger = require('../utils/Logger');
+
+l = new Logger('uRequireConfigMasterDefaults');
+
+rJSON = function(file) {
+ return JSON.parse(_fs.readFileSync(file, 'utf-8'));
+};
+
+module.exports = uRequireConfig = {
+ bundle: {
+ /*
+ Name of the bundle, eg 'MyLibrary'
+
+ @optional
+
+ `bundleName` its self can be derived from:
+ - if using grunt, it defaults to the multi-task @target (eg {urequire: 'MyBundlename': {bundle : {}, build:{} }}
+
+ @todo:
+ - --outputPath,
+ - filename part, if 'combined' is used eg if its 'abcProject/abc.js', then 'abc'
+ - folder name, if other template is used eg 'build/abcProject' gives 'abcProject'
+
+ @note: `bundleName` & is the (1st) default for 'main'
+ */
+
+ bundleName: void 0,
+ /*
+ The "main" / "index" module file of your bundle.
+
+ * Used as 'name' / 'include' on RequireJS build.js.
+ It should be the 'entry' point module of your bundle, where all dependencies are `require`'d.
+ r.js recursivelly adds them the combined file.
+
+ * It is also used to as the initiation `require` on your combined bundle.
+ It is the module just kicks off the app and/or requires all your other library modules.
+
+ * Defaults to 'bundleName', 'index', 'main' etc, the first one that is found in uModules.
+ */
+
+ main: void 0,
+ bundlePath: '',
+ /*
+ Everything that matches these is not proccessed.
+
+ Can be a String, a RegExp or a Fucntion(item)
+ Or an array of those
+
+ @example
+ [ "requirejs_plugins/text.js", /^draft/, function(x){return x === 'badApple.js'}]
+ */
+
+ excludes: [],
+ /*
+ List of modules to include, WITH extension.
+ Can A string, RegExp or a Function(item)
+
+ @example ['module1.js', 'myLibs/mylib1.js']
+ */
+
+ includes: [/.*\.(coffee)$/i, /.*\.(js|javascript)$/i],
+ /*
+ Where to map `/` when running in node. On RequireJS its http-server's root.
+
+ Can be absolute or relative to bundle. Defaults to bundle.
+ @example "/var/www" or "/../../fakeWebRoot"
+ */
+
+ webRootMap: '.',
+ dependencies: {
+ /*
+ Each (global) dependency has one or more variables it is exported as, eg `jquery: ["$", "jQuery"]`
+
+ They can be infered from the code of course (AMD only for now), but it good to list them here also.
+
+ They are used to 'fetch' the global var at runtime, eg, when `combined:'almond'` is used.
+
+ In case they are missing from modules (i.e u use the 'nodejs' module format only),
+ and aren't here either, 'almond' build will fail.
+
+ Also you can add a different var name that should be globally looked up.
+ */
+
+ variableNames: {
+ lodash: "_",
+ underscore: "_",
+ jquery: ["$", "jQuery"],
+ backbone: "Backbone",
+ knockout: ["ko", 'Knockout']
+ },
+ /*
+ depe
+ { dependency: varName(s) *}
+ or
+ ['dep1', 'dep2'] (with discovered or ../variableNames names
+
+ Each dep will be available in the *whole bundle* under varName(s)
+
+ @example {
+ 'underscore': '_'
+ 'jquery': ["$", "jQuery"]
+ 'models/PersonModel': ['persons', 'personsModel']
+ }
+ @todo: rename to exports.bundle ?
+ */
+
+ bundleExports: {}
+ }
+ },
+ /*
+
+ Build : Defines the conversion, such as *where* and *what* to output
+ */
+
+ build: {
+ /*
+ Output converted files onto this
+
+ * directory
+ * filename (if combining)
+ * function @todo: NOT IMPLEMENTED
+
+ #todo: if ommited, requirejs.buildjs.baseUrl is used ?
+ @example 'build/code'
+ */
+
+ outputPath: '',
+ /*
+ Output on the same directory as bundlePath.
+
+ Useful if your sources are not `real sources` eg. you use coffeescript :-).
+ WARNING: -f ignores --outputPath
+ */
+
+ forceOverwriteSources: false,
+ /*
+ String in ['UMD', 'AMD', 'nodejs', 'combined'] @todo: or an object with those as keys + more stuff!
+ */
+
+ template: {
+ name: 'UMD'
+ },
+ watch: false,
+ /*
+ ignore exports
+ # @todo: NOT IMPLEMENTED.
+ */
+
+ noRootExports: false,
+ noBundleExports: false,
+ /*
+ *Web/AMD side only option* :
+
+ By default, ALL require('') deps appear on []. to prevent RequireJS to scan @ runtime.
+
+ With --s you can allow `require('')` scan @ runtime, for source modules that have no [] deps (i.e. nodejs source modules).
+ NOTE: modules with rootExports / noConflict() always have `scanAllow: false`
+ */
+
+ scanAllow: false,
+ /*
+ Pre-require all deps on node, even if they arent mapped to parameters, just like in AMD deps [].
+ Preserves same loading order, but a possible slower starting up. They are cached nevertheless, so you might gain speed later.
+ */
+
+ allNodeRequires: false,
+ verbose: false,
+ debugLevel: 0,
+ "continue": false,
+ uglify: false
+ },
+ /*
+ Runtime settings - these are used only when executing on nodejs.
+ They are written out as a "uRequire.config.js" module used at runtime on the nodejs side.
+ @todo: NOT IMPLEMENTED
+ */
+
+ requirejs: {
+ paths: {
+ src: "../../src",
+ text: "requirejs_plugins/text",
+ json: "requirejs_plugins/json"
+ },
+ baseUrl: "../code"
+ },
+ "build.js": {
+ /*
+ piggy back on this? see `appDir` in https://github.com/jrburke/r.js/blob/master/build/example.build.js
+ @todo: NOT IMPLEMENTED -
+ */
+
+ appDir: "some/path/",
+ paths: {
+ lodash: "../../libs/lodash.min"
+ },
+ optimize: "none"
+ }
+};
View
300 build/code/moduleManipulation/ModuleManipulator.js
@@ -0,0 +1,300 @@
+// Generated by CoffeeScript 1.4.0
+var JSManipulator, Logger, ModuleManipulator, l, parser, proc, seekr, _, _B,
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+_ = require('lodash');
+
+_B = require('uberscore');
+
+Logger = require('../utils/Logger');
+
+l = new Logger('ModuleManipulator');
+
+seekr = require('./seekr');
+
+parser = require("uglify-js").parser;
+
+proc = require("uglify-js").uglify;
+
+JSManipulator = (function() {
+
+ function JSManipulator(js, options) {
+ var _base, _ref;
+ this.js = js != null ? js : '';
+ this.options = options != null ? options : {};
+ this.safeEval = __bind(this.safeEval, this);
+
+ if ((_ref = (_base = this.options).beautify) == null) {
+ _base.beautify = false;
+ }
+ try {
+ this.AST = parser.parse(this.js);
+ } catch (err) {
+ err.urequireError = "uRequire : error parsing javascript source.\nMake sure uRequire is using Uglify 1.x, (and NOT 2.x).\nOtherwise, check you Javascript source!\nError=\n";
+ l.err(err.urequireError, err);
+ throw err;
+ }
+ }
+
+ JSManipulator.prototype.toCode = function(astCode) {
+ if (astCode == null) {
+ astCode = this.AST;
+ }
+ return proc.gen_code(astCode, {
+ beautify: this.options.beautify
+ });
+ };
+
+ JSManipulator.prototype.evalByType = _B.certain({
+ 'string': function(val) {
+ return (this.toCode(val)).replace(/\"|\'/g, '');
+ },
+ '*': function(val) {
+ return this.toCode(val);
+ }
+ }, '*');
+
+ JSManipulator.prototype.safeEval = function(elem) {
+ return this.evalByType(elem[0]).call(this, elem);
+ };
+
+ JSManipulator.prototype.readAST = {
+ 'call': function(ast) {
+ var dot, dotExpr, expr, name;
+ expr = ast[1];
+ name = dot = '';
+ dotExpr = expr;
+ while (dotExpr[0] === 'dot') {
+ name = "" + dotExpr[2] + dot + name;
+ dotExpr = dotExpr[1];
+ dot = '.';
+ }
+ name = dotExpr[1] + dot + name;
+ return {
+ name: name,
+ expr: expr,
+ args: ast[2]
+ };
+ },
+ 'object': function(ast) {
+ var _ref;
+ return {
+ top: (_ref = ast[1][0]) != null ? _ref[0] : void 0,
+ props: ast[1][0][1]
+ };
+ },
+ 'function': function(ast) {
+ return {
+ name: ast[1],
+ args: ast[2],
+ body: ast[3]
+ };
+ },
+ 'defun': function(ast) {
+ return {
+ name: ast[1],
+ args: ast[2],
+ body: ast[3]
+ };
+ }
+ };
+
+ return JSManipulator;
+
+})();
+
+ModuleManipulator = (function(_super) {
+
+ __extends(ModuleManipulator, _super);
+
+ function ModuleManipulator(js, options) {
+ var _base;
+ this.options = options != null ? options : {};
+ ModuleManipulator.__super__.constructor.apply(this, arguments);
+ (_base = this.options).extractFactory || (_base.extractFactory = false);
+ this.moduleInfo = {};
+ this.AST_FactoryBody = null;
+ }
+
+ ModuleManipulator.prototype._gatherItemsInSegments = function(astArray, segments) {
+ var elType, elem, _base, _i, _len, _name, _results;
+ if (!_(astArray).isArray()) {
+ astArray = [astArray];
+ }
+ _results = [];
+ for (_i = 0, _len = astArray.length; _i < _len; _i++) {
+ elem = astArray[_i];
+ elType = elem[0];
+ if (!segments[elType]) {
+ if (segments['*']) {
+ elType = '*';
+ } else {
+ break;
+ }
+ }
+ _results.push(((_base = this.moduleInfo)[_name = segments[elType]] || (_base[_name] = [])).push(this.safeEval(elem)));
+ }
+ return _results;
+ };
+
+ ModuleManipulator.prototype.extractModuleInfo = function() {
+ var UMDSeeker, defineAMDSeeker, requireCallsSeeker, urequireJsonHeaderSeeker;
+ urequireJsonHeaderSeeker = {
+ level: {
+ min: 4,
+ max: 4
+ },
+ '_object': function(o) {
+ var properties;
+ if (o.top === 'urequire') {
+ properties = eval("(" + (this.toCode(o.props)) + ")");
+ this.moduleInfo = _.extend(this.moduleInfo, properties);
+ return 'stop';
+ }
+ }
+ };
+ defineAMDSeeker = {
+ level: {
+ min: 4,
+ max: 4
+ },
+ '_call': function(c) {
+ var amdDeps, factoryFn, fn, _ref;
+ if ((_ref = c.name) === 'define' || _ref === 'require') {
+ if (c.args.length === 3 && c.args[0][0] === 'string' && c.args[1][0] === 'array' && c.args[2][0] === 'function') {
+ this.moduleInfo.moduleName = this.safeEval(c.args[0]);
+ amdDeps = c.args[1][1];
+ factoryFn = c.args[2];
+ } else {
+ if (c.args.length === 2 && c.args[0][0] === 'array' && c.args[1][0] === 'function') {
+ amdDeps = c.args[0][1];
+ factoryFn = c.args[1];
+ } else {
+ if (c.args.length === 1 && c.args[0][0] === 'function') {
+ amdDeps = [];
+ factoryFn = c.args[0];
+ }
+ }
+ }
+ if (factoryFn) {
+ fn = this.readAST['function'](factoryFn);
+ if (!_(fn.args).isEmpty()) {
+ this.moduleInfo.parameters = fn.args;
+ }
+ this.AST_FactoryBody = ['block', fn.body];
+ if (this.options.extractFactory) {
+ this.moduleInfo.factoryBody = this.toCode(this.AST_FactoryBody);
+ this.moduleInfo.factoryBody = this.moduleInfo.factoryBody.slice(1, +(this.moduleInfo.factoryBody.length - 2) + 1 || 9e9).trim();
+ }
+ this._gatherItemsInSegments(amdDeps, {
+ 'string': 'arrayDependencies',
+ '*': 'untrustedArrayDependencies'
+ });
+ this.moduleInfo.moduleType = 'AMD';
+ this.moduleInfo.amdCall = c.name;
+ return 'stop';
+ }
+ }
+ }
+ };
+ seekr([urequireJsonHeaderSeeker, defineAMDSeeker], this.AST, this.readAST, this);
+ if (this.moduleInfo.moduleType !== 'AMD') {
+ UMDSeeker = {
+ level: {
+ min: 4,
+ max: 5
+ },
+ '_function': function(f) {
+ if (_(f.args).isEqual(['root', 'factory'])) {
+ this.moduleInfo.moduleType = 'UMD';
+ this.AST_FactoryBody = null;
+ return 'stop';
+ }
+ }
+ };
+ seekr([UMDSeeker], this.AST, this.readAST, this);
+ if (this.moduleInfo.moduleType !== 'UMD') {
+ this.moduleInfo.moduleType = 'nodejs';
+ this.AST_FactoryBody = this.AST;
+ if (this.options.extractFactory) {
+ this.moduleInfo.factoryBody = this.js;
+ }
+ }
+ }
+ if (this.AST_FactoryBody) {
+ requireCallsSeeker = {
+ '_call': function(c) {
+ if (c.name === 'require') {
+ if (c.args[0][0] === 'array') {
+ return this._gatherItemsInSegments(c.args[0][1], {
+ 'string': 'asyncDependencies',
+ '*': 'untrustedAsyncDependencies'
+ });
+ } else {
+ return this._gatherItemsInSegments(c.args, {
+ 'string': 'requireDependencies',
+ '*': 'untrustedRequireDependencies'
+ });
+ }
+ }
+ }
+ };
+ seekr([requireCallsSeeker], this.AST_FactoryBody, this.readAST, this);
+ if (!_(this.moduleInfo.requireDependencies).isEmpty()) {
+ this.moduleInfo.requireDependencies = _.difference(_.uniq(this.moduleInfo.requireDependencies), this.moduleInfo.arrayDependencies);
+ }
+ }
+ return this.moduleInfo;
+ };
+
+ ModuleManipulator.prototype._replaceASTStringElements = function(astArray, replacements) {
+ var elem, _i, _len, _results;
+ if (!_(astArray).isArray()) {
+ astArray = [astArray];
+ }
+ _results = [];
+ for (_i = 0, _len = astArray.length; _i < _len; _i++) {
+ elem = astArray[_i];
+ if (elem[0] === 'string') {
+ if (replacements[elem[1]]) {
+ _results.push(elem[1] = replacements[elem[1]]);
+ } else {
+ _results.push(void 0);
+ }
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ };
+
+ ModuleManipulator.prototype.getFactoryWithReplacedRequires = function(requireReplacements) {
+ var fb, requireCallsReplacerSeeker;
+ if (this.AST_FactoryBody) {
+ requireCallsReplacerSeeker = {
+ '_call': function(c) {
+ if (c.name === 'require') {
+ if (c.args[0][0] === 'array') {
+ return this._replaceASTStringElements(c.args[0][1], requireReplacements);
+ } else if (c.args[0][0] === 'string') {
+ return this._replaceASTStringElements(c.args, requireReplacements);
+ }
+ }
+ }
+ };
+ seekr([requireCallsReplacerSeeker], this.AST_FactoryBody, this.readAST, this);
+ fb = (this.toCode(this.AST_FactoryBody)).trim();
+ if (this.moduleInfo.moduleType === 'AMD') {
+ fb = fb.slice(1, +(fb.length - 2) + 1 || 9e9).trim();
+ }
+ return this.moduleInfo.factoryBody = fb;
+ }
+ };
+
+ return ModuleManipulator;
+
+})(JSManipulator);
+
+module.exports = ModuleManipulator;
View
54 build/code/moduleManipulation/seekr.js
@@ -0,0 +1,54 @@
+// Generated by CoffeeScript 1.4.0
+var log, seekr, _;
+
+_ = require('lodash');
+
+log = console.log;
+
+seekr = function(seekers, data, stackreader, ctx, _level, _continue, _stack) {
+ if (_level == null) {
+ _level = 0;
+ }
+ if (_continue == null) {
+ _continue = true;
+ }
+ if (_stack == null) {
+ _stack = [];
+ }
+ _level++;
+ if (_level === 1) {
+ if (!_(seekers).isArray()) {
+ seekers = [seekers];
+ }
+ }
+ if (_continue) {
+ return _(data).each(function(dataItem) {
+ var deadSeekers, s, skr, stacktop, _i, _len, _ref, _ref1, _ref2, _ref3;
+ if (_(dataItem).isObject() || _(dataItem).isArray()) {
+ _stack.push(dataItem);
+ seekr(seekers, dataItem, stackreader, ctx, _level, _continue, _stack);
+ return _stack.pop();
+ } else {
+ stacktop = _stack[_stack.length - 1];
+ deadSeekers = [];
+ for (_i = 0, _len = seekers.length; _i < _len; _i++) {
+ skr = seekers[_i];
+ if (_level >= ((_ref = (_ref1 = skr.level) != null ? _ref1.min : void 0) != null ? _ref : 0) && _level <= ((_ref2 = (_ref3 = skr.level) != null ? _ref3.max : void 0) != null ? _ref2 : 99999)) {
+ if (_(skr['_' + dataItem]).isFunction()) {
+ if (stackreader[dataItem]) {
+ s = skr['_' + dataItem].call(ctx, stackreader[dataItem](stacktop));
+ if (s === 'stop') {
+ deadSeekers.push(skr);
+ }
+ }
+ }
+ }
+ }
+ seekers = _.difference(seekers, deadSeekers);
+ return _continue = !_(seekers).isEmpty();
+ }
+ });
+ }
+};
+
+module.exports = seekr;
View
97 build/code/paths/pathRelative.js
@@ -0,0 +1,97 @@
+// Generated by CoffeeScript 1.4.0
+var pathRelative;
+
+pathRelative = function(from, to, options) {
+ var commonPath, finalPath, lastFrom, lastTo, part, path, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
+ options || (options = {});
+ _ref = (function() {
+ var _i, _len, _ref, _results;
+ _ref = [from, to];
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ path = _ref[_i];
+ _results.push((path.replace(/\\/g, '/')).split('/'));
+ }
+ return _results;
+ })(), from = _ref[0], to = _ref[1];
+ _ref1 = (function() {
+ var _i, _len, _ref1, _results;
+ _ref1 = [from, to];
+ _results = [];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ path = _ref1[_i];
+ _results.push((function() {
+ var _j, _len1, _results1;
+ _results1 = [];
+ for (_j = 0, _len1 = path.length; _j < _len1; _j++) {
+ part = path[_j];
+ if (part !== '' && part !== '.') {
+ _results1.push(part);
+ }
+ }
+ return _results1;
+ })());
+ }
+ return _results;
+ })(), from = _ref1[0], to = _ref1[1];
+ _ref2 = [from, to];
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ path = _ref2[_i];
+ if (path.length === 0) {
+ return null;
+ }
+ }
+ commonPath = [];
+ while ((lastFrom = from.shift()) === (lastTo = to.shift()) && (from.length > 0 || to.length > 0)) {
+ commonPath.push(lastFrom);
+ }
+ finalPath = [];
+ if (commonPath.length > 0 || lastFrom === lastTo) {
+ if (lastFrom !== lastTo) {
+ if (lastFrom) {
+ from.unshift(lastFrom);
+ }
+ if (lastTo) {
+ to.unshift(lastTo);
+ }
+ for (_j = 0, _len1 = from.length; _j < _len1; _j++) {
+ part = from[_j];
+ if (part !== '..') {
+ finalPath.push('..');
+ } else {
+ if (finalPath.length > 0) {
+ finalPath.pop();
+ } else {
+ if (commonPath.length > 0) {
+ to.unshift(commonPath.pop());
+ } else {
+ return null;
+ }
+ }
+ }
+ }
+ for (_k = 0, _len2 = to.length; _k < _len2; _k++) {
+ part = to[_k];
+ if (part !== '..') {
+ finalPath.push("" + part);
+ } else {
+ if (finalPath[finalPath.length - 1] === '..') {
+ finalPath.push('..');
+ } else {
+ finalPath.pop();
+ }
+ }
+ }
+ }
+ if (options.dot4Current) {
+ if (finalPath[0] !== '..') {
+ finalPath.unshift('.');
+ }
+ }
+ return finalPath.join("/");
+ } else {
+ return null;
+ }
+};
+
+module.exports = pathRelative;
View
23 build/code/paths/resolvePathToFromModuleRoot.js
@@ -0,0 +1,23 @@
+// Generated by CoffeeScript 1.4.0
+var resolvePathToFromModuleRoot;
+
+resolvePathToFromModuleRoot = function(modyle, pathFromModuleRoot) {
+ var pathRelative, res, stepsToBundleRoot, _path;
+ pathRelative = require('./pathRelative');
+ _path = require('path');
+ stepsToBundleRoot = pathRelative("$/" + (_path.dirname(modyle)), '$/', {
+ dot4Current: true
+ });
+ if (pathFromModuleRoot) {
+ if (pathFromModuleRoot[0] === '.') {
+ res = _path.normalize(stepsToBundleRoot + '/' + pathFromModuleRoot);
+ } else {
+ res = pathFromModuleRoot;
+ }
+ } else {
+ res = stepsToBundleRoot;
+ }
+ return res.replace(/\\/g, '/');
+};
+
+module.exports = resolvePathToFromModuleRoot;
View
77 build/code/paths/upath.js
@@ -0,0 +1,77 @@
+// Generated by CoffeeScript 1.4.0
+var fName, fn, upath, _, _path,
+ __slice = [].slice;
+
+_ = require('lodash');
+
+_.mixin((require('underscore.string')).exports());
+
+_path = require('path');
+
+/*
+ upath is a proxy to node's 'path', replacing '\' with '/' for all string results :-)
+
+ And adding some features ?...
+*/
+
+
+upath = {};
+
+for (fName in _path) {
+ fn = _path[fName];
+ if (_.isFunction(fn)) {
+ upath[fName] = (function(fName) {
+ return function() {
+ var p, res;
+ p = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
+ res = _path[fName].apply(_path, p);
+ if (_.isString(res)) {
+ return res.replace(/\\/g, '/');
+ } else {
+ return res;
+ }
+ };
+ })(fName);
+ }
+}
+
+/*
+ @return file + ext, if it doesnt have it
+ eg to add .js to output .js file
+*/
+
+
+upath.addExt = function(file, ext) {
+ return file + (_(file).endsWith(ext) ? '' : ext);
+};
+
+upath.trimExt = function(file) {
+ return file.slice(0, +((file.length - this.extname(file).length) - 1) + 1 || 9e9);
+};
+
+/*
+ @return filename with changed extension
+*/
+
+
+upath.changeExt = function(file, ext) {
+ return upath.trimExt(file) + (ext[0] === '.' ? ext : '.' + ext);
+};
+
+/*
+ Add .ext, ONLY if filename doesn't have an extension (any).
+ Extensions are considered to be up to 4 chars long
+*/
+
+
+upath.defaultExt = function(file, ext) {
+ var oldExt;
+ oldExt = upath.extname(file);
+ if (oldExt && oldExt.length <= 4 && oldExt.length >= 1) {
+ return file;
+ } else {
+ return upath.addExt(file, ext);
+ }
+};
+
+module.exports = upath;
View
117 build/code/process/Build.js
@@ -0,0 +1,117 @@
+// Generated by CoffeeScript 1.4.0
+var Build, Logger, YADC, l, uRequireConfigMasterDefaults, upath, _, _B, _fs, _wrench;
+
+_ = require('lodash');
+
+_B = require('uberscore');
+
+_fs = require('fs');
+
+_wrench = require('wrench');
+
+Logger = require('../utils/Logger');
+
+l = new Logger('Build');
+
+upath = require('../paths/upath');
+
+uRequireConfigMasterDefaults = require('../config/uRequireConfigMasterDefaults');
+
+module.exports = Build = (function() {
+ var _this = this;
+
+ Function.prototype.property = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(this.prototype, n, d));
+ }
+ return _results;
+ };
+
+ Function.prototype.staticProperty = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(Build.prototype, n, d));
+ }
+ return _results;
+ };
+
+ function Build() {
+ this._constructor.apply(this, arguments);
+ }
+
+ Build.prototype._constructor = function(buildCfg) {
+ _.extend(this, _B.deepCloneDefaults(buildCfg, uRequireConfigMasterDefaults.build));
+ if (!this.out) {
+ return this.out = Build.outputModuleToFile;
+ }
+ };
+
+ Build.templates = ['UMD', 'AMD', 'nodejs', 'combined'];
+
+ Build.moduleExtensions = ['js', 'javascript', 'coffee'];
+
+ Build.outputModuleToFile = function(modulePath, content) {
+ return Build.outputToFile(upath.join(this.outputPath, "" + modulePath + ".js"), content);
+ };
+
+ Build.outputToFile = function(outputFilename, content) {
+ l.debug(5, "Writting file '" + outputFilename + "' (" + content.length + " chars)");
+ try {
+ if (!_fs.existsSync(upath.dirname(outputFilename))) {
+ l.verbose("Creating directory '" + (upath.dirname(outputFilename)) + "'");
+ _wrench.mkdirSyncRecursive(upath.dirname(outputFilename));
+ }
+ _fs.writeFileSync(outputFilename, content, 'utf-8');
+ if (this.watch) {
+ return l.verbose("Written file '" + outputFilename + "'");
+ }
+ } catch (err) {
+ err.uRequire = "uRequire: error outputToFile '" + outputFilename + "'";
+ l.err(err.uRequire);
+ throw err;
+ }
+ };
+
+ Build.copyFileSync = function(srcFile, destFile) {
+ var BUF_LENGTH, buff, bytesRead, fdr, fdw, pos;
+ l.debug(30, "copyFileSync {src='" + srcFile + "', dst='" + destFile + "'");
+ try {
+ BUF_LENGTH = 64 * 1024;
+ buff = new Buffer(BUF_LENGTH);
+ fdr = _fs.openSync(srcFile, 'r');
+ if (!(_fs.existsSync(upath.dirname(destFile)))) {
+ l.verbose("Creating directory " + (upath.dirname(destFile)));
+ _wrench.mkdirSyncRecursive(upath.dirname(destFile));
+ }
+ fdw = _fs.openSync(destFile, 'w');
+ bytesRead = 1;
+ pos = 0;
+ while (bytesRead > 0) {
+ bytesRead = _fs.readSync(fdr, buff, 0, BUF_LENGTH, pos);
+ _fs.writeSync(fdw, buff, 0, bytesRead);
+ pos += bytesRead;
+ }
+ _fs.closeSync(fdr);
+ return _fs.closeSync(fdw);
+ } catch (err) {
+ err.uRequire = "uRequire: error copyFileSync from '" + srcFile + "' to '" + destFile + "'";
+ l.err(err.uRequire);
+ throw err;
+ }
+ };
+
+ return Build;
+
+}).call(this);
+
+if (Logger.prototype.debugLevel > 90) {
+ YADC = require('YouAreDaChef').YouAreDaChef;
+ YADC(Build).before(/_constructor/, function(match, buildCfg) {
+ return l.debug("Before '" + match + "' with buildCfg = \n", _.omit(buildCfg, []));
+ });
+}
View
473 build/code/process/Bundle.js
@@ -0,0 +1,473 @@
+// Generated by CoffeeScript 1.4.0
+var AlmondOptimizationTemplate, Build, Bundle, BundleBase, DependenciesReporter, Dependency, Logger, UModule, YADC, getFiles, l, uRequireConfigMasterDefaults, upath, _, _B, _fs, _wrench,
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+_ = require('lodash');
+
+_.mixin((require('underscore.string')).exports());
+
+_B = require('uberscore');
+
+_fs = require('fs');
+
+_wrench = require('wrench');
+
+Logger = require('../utils/Logger');
+
+l = new Logger('Bundle');
+
+upath = require('../paths/upath');
+
+getFiles = require("./../utils/getFiles");
+
+uRequireConfigMasterDefaults = require('../config/uRequireConfigMasterDefaults');
+
+AlmondOptimizationTemplate = require('../templates/AlmondOptimizationTemplate');
+
+Dependency = require('../Dependency');
+
+DependenciesReporter = require('./../DependenciesReporter');
+
+UModule = require('./UModule');
+
+Build = require('./Build');
+
+BundleBase = require('./BundleBase');
+
+/*
+*/
+
+
+Bundle = (function(_super) {
+ var filesFilter, getFilesFactory, _ref,
+ _this = this;
+
+ __extends(Bundle, _super);
+
+ Function.prototype.property = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(this.prototype, n, d));
+ }
+ return _results;
+ };
+
+ Function.prototype.staticProperty = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(Bundle.prototype, n, d));
+ }
+ return _results;
+ };
+
+ function Bundle() {
+ this._constructor.apply(this, arguments);
+ }
+
+ Bundle.prototype.interestingDepTypes = ['notFoundInBundle', 'untrustedRequireDependencies', 'untrustedAsyncDependencies'];
+
+ Bundle.staticProperty({
+ requirejs: {
+ get: function() {
+ return require('requirejs');
+ }
+ }
+ });
+
+ Bundle.prototype._constructor = function(bundleCfg) {
+ _.extend(this, _B.deepCloneDefaults(bundleCfg, uRequireConfigMasterDefaults.bundle));
+ this.uModules = {};
+ this.loadModules();
+ /* handle bundle.bundleName & bundle.main
+ */
+
+ return this.reporter = new DependenciesReporter(this.interestingDepTypes);
+ };
+
+ /*
+ Read / refresh all files in directory.
+ Not run everytime there is a file added/removed, unless we need to:
+ Runs initially and in unkonwn -watch / refresh situations
+ */
+
+
+ _ref = {
+ filenames: function() {
+ return true;
+ },
+ moduleFilenames: function(mfn) {
+ return _B.inAgreements(mfn, this.includes) && !_B.inAgreements(mfn, this.excludes);
+ }
+ };
+ for (getFilesFactory in _ref) {
+ filesFilter = _ref[getFilesFactory];
+ Bundle.property(_B.okv({}, getFilesFactory, {
+ get: (function(getFilesFactory, filesFilter) {
+ return function() {
+ var deletedFiles, existingFiles, file, files, newFiles, _i, _len, _name;
+ existingFiles = (this[_name = "_" + getFilesFactory] || (this[_name] = []));
+ try {
+ files = getFiles(this.bundlePath, _.bind(filesFilter, this));
+ } catch (err) {
+ err.uRequire = "*uRequire " + l.VERSION + "*: Something went wrong reading from '" + this.bundlePath + "'.";
+ l.err(err.uRequire);
+ throw err;
+ }
+ newFiles = _.difference(files, existingFiles);
+ if (!_.isEmpty(newFiles)) {
+ l.verbose("New " + getFilesFactory + " :\n", newFiles);
+ for (_i = 0, _len = newFiles.length; _i < _len; _i++) {
+ file = newFiles[_i];
+ existingFiles.push(file);
+ }
+ }
+ deletedFiles = _.difference(existingFiles, files);
+ if (!_.isEmpty(deletedFiles)) {
+ l.verbose("Deleted " + getFilesFactory + " :\n", deletedFiles);
+ this.deleteModules(deletedFiles);
+ this["_" + getFilesFactory] = files;
+ }
+ return files;
+ };
+ })(getFilesFactory, filesFilter)
+ }, Bundle));
+ }
+
+ /*
+ Processes each module, as instructed by `watcher` in a [] paramor read file system (@moduleFilenames)
+ @param @build - see `config/uRequireConfigMasterDefaults.coffee`
+ @param String or []<String> with filenames to process.
+ @default read files from filesystem (property @moduleFilenames)
+ */
+
+
+ Bundle.prototype.loadModules = function(moduleFilenames) {
+ var fullModulePath, moduleFN, moduleSource, _i, _len, _ref1, _results;
+ if (moduleFilenames == null) {
+ moduleFilenames = this.moduleFilenames;
+ }
+ _ref1 = _B.arrayize(moduleFilenames);
+ _results = [];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ moduleFN = _ref1[_i];
+ fullModulePath = "" + this.bundlePath + "/" + moduleFN;
+ try {
+ moduleSource = _fs.readFileSync(fullModulePath, 'utf-8');
+ if (this.uModules[moduleFN]) {
+ if (uM.sourceCode !== moduleSource) {
+ delete this.uModule[moduleFN];
+ }
+ }
+ if (!this.uModules[moduleFN]) {
+ _results.push(this.uModules[moduleFN] = new UModule(this, moduleFN, moduleSource));
+ } else {
+ _results.push(void 0);
+ }
+ } catch (err) {
+ l.debug(80, err);
+ if (!_fs.existsSync(fullModulePath)) {
+ l.log("Missing file '" + fullModulePath + "', removing module '" + moduleFN + "'");
+ if (this.uModules[moduleFN]) {
+ _results.push(delete this.uModules[moduleFN]);
+ } else {
+ _results.push(void 0);
+ }
+ } else {
+ err.uRequire = "*uRequire " + l.VERSION + "*: Something went wrong while processing '" + fullModulePath + "', for module '" + moduleFN + "'.";
+ l.err(err.uRequire);
+ throw err;
+ }
+ }
+ }
+ return _results;
+ };
+
+ /*
+ @build / convert all uModules that have changed since last @build
+ */
+
+
+ Bundle.prototype.buildChangedModules = function(build) {
+ var haveChanges, mfn, uModule, _ref1;
+ this.build = build;
+ if (this.build.template.name === 'combined') {
+ if (!this.build.combinedFile) {
+ this.build.combinedFile = upath.changeExt(this.build.outputPath, '.js');
+ this.build.outputPath = "" + this.build.combinedFile + "__temp";
+ l.debug(95, "Setting @build.combinedFile = '" + this.build.outputPath + "' and @build.outputPath = '" + this.build.outputPath + "'");
+ }
+ }
+ this.copyNonModuleFiles();
+ haveChanges = false;
+ _ref1 = this.uModules;
+ for (mfn in _ref1) {
+ uModule = _ref1[mfn];
+ if (!uModule.convertedJs) {
+ haveChanges = true;
+ uModule.convert(this.build);
+ if (_.isFunction(this.build.out)) {
+ this.build.out(uModule.modulePath, uModule.convertedJs);
+ }
+ }
+ }
+ if (!_.isEmpty(this.reporter.reportData)) {
+ l.log('\n########### urequire, final report ########### :\n', this.reporter.getReport());
+ }
+ if (this.build.template.name === 'combined') {
+ if (haveChanges) {
+ return this.combine(this.build);
+ } else {
+ return this.build.done(true);
+ }
+ } else {
+ return this.build.done(true);
+ }
+ };
+
+ Bundle.prototype.getRequireJSConfig = function() {
+ return {
+ paths: {
+ text: "requirejs_plugins/text",
+ json: "requirejs_plugins/json"
+ }
+ };
+ };
+
+ Bundle.prototype.copyAlmondJs = function() {
+ try {
+ return Build.copyFileSync("" + __dirname + "/../../../node_modules/almond/almond.js", "" + this.build.outputPath + "/almond.js");
+ } catch (err) {
+ err.uRequire = "uRequire: error copying almond.js from uRequire's installation node_modules - is it installed ?\nTried: '" + __dirname + "/../../../node_modules/almond/almond.js'";
+ l.err(err.uRequire);
+ throw err;
+ }
+ };
+
+ Bundle.prototype.copyNonModuleFiles = function() {
+ var fn, nonModules, _i, _len, _results;
+ nonModules = (function() {
+ var _i, _len, _ref1, _results;
+ _ref1 = this.filenames;
+ _results = [];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ fn = _ref1[_i];
+ if (__indexOf.call(this.moduleFilenames, fn) < 0) {
+ _results.push(fn);
+ }
+ }
+ return _results;
+ }).call(this);
+ if (!_.isEmpty(nonModules)) {
+ l.verbose("Copying non-module/excluded files : \n", nonModules);
+ _results = [];
+ for (_i = 0, _len = nonModules.length; _i < _len; _i++) {
+ fn = nonModules[_i];
+ _results.push(Build.copyFileSync("" + this.bundlePath + "/" + fn, "" + this.build.outputPath + "/" + fn));
+ }
+ return _results;
+ }
+ };
+
+ /*
+ Copy all bundle's webMap dependencies to outputPath
+ @todo: should copy dep.plugin & dep.resourceName separatelly
+ */
+
+
+ Bundle.prototype.copyWebMapDeps = function() {
+ var depName, webRootDeps, _i, _len, _results;
+ webRootDeps = _.keys(this.getDepsVars({
+ depType: Dependency.TYPES.webRootMap
+ }));
+ if (!_.isEmpty(webRootDeps)) {
+ l.verbose("Copying webRoot deps :\n", webRootDeps);
+ _results = [];
+ for (_i = 0, _len = webRootDeps.length; _i < _len; _i++) {
+ depName = webRootDeps[_i];
+ _results.push(Build.copyFileSync("" + this.webRoot + depName, "" + this.build.outputPath + depName));
+ }
+ return _results;
+ }
+ };
+
+ Bundle.prototype.deleteModules = function(modules) {
+ var m, _i, _len, _results;
+ if (this.uModules[m]) {
+ _results = [];
+ for (_i = 0, _len = modules.length; _i < _len; _i++) {
+ m = modules[_i];
+ _results.push(l.debug(50, "delete " + this.uModules[m]));
+ }
+ return _results;
+ }
+ };
+
+ /*
+ */
+
+
+ Bundle.prototype.combine = function(build) {
+ var almondTemplates, fileName, genCode, mainModuleCandidate, rjsConfig, _i, _len, _ref1, _ref2,
+ _this = this;
+ this.build = build;
+ if (!this.main) {
+ _ref1 = [this.bundleName, 'index', 'main'];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ mainModuleCandidate = _ref1[_i];
+ if (!(mainModuleCandidate && !this.main)) {
+ continue;
+ }
+ this.main = _.find(this.moduleFilenames, function(mf) {
+ var ext, _j, _len1, _ref2;
+ _ref2 = Build.moduleExtensions;
+ for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
+ ext = _ref2[_j];
+ if (mf === mainModuleCandidate + ("." + ext)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ if (this.main) {
+ l.warn("combine() note: 'bundle.main', your *entry-point module* was missing from bundle config(s).\nIt's defaulting to '" + (upath.trimExt(this.main)) + "', from existing '" + this.bundlePath + "/" + this.main + "' module in your bundlePath.");
+ this.main = upath.trimExt(this.main);
+ }
+ }
+ }
+ if (!this.main) {
+ l.err("Quiting cause 'bundle.main' is missing (after so much effort).\nNo module found either as bundleName = '" + this.bundleName + "', nor as ['index', 'main'].");
+ return this.build.done(false);
+ } else {
+ almondTemplates = new AlmondOptimizationTemplate({
+ globalDepsVars: this.getDepsVars({
+ depType: Dependency.TYPES.global
+ }),
+ main: this.main
+ });
+ _ref2 = almondTemplates.dependencyFiles;
+ for (fileName in _ref2) {
+ genCode = _ref2[fileName];
+ Build.outputToFile("" + this.build.outputPath + "/" + fileName + ".js", genCode);
+ }
+ this.copyAlmondJs();
+ this.copyWebMapDeps();
+ try {
+ _fs.unlinkSync(this.build.combinedFile);
+ } catch (err) {
+
+ }
+ rjsConfig = {
+ paths: _.extend(almondTemplates.paths, this.getRequireJSConfig().paths),
+ wrap: almondTemplates.wrap,
+ baseUrl: this.build.outputPath,
+ include: this.main,
+ out: this.build.combinedFile,
+ optimize: "none",
+ name: 'almond'
+ };
+ if (l.debugLevel >= 90) {
+ rjsConfig.logLevel = 0;
+ }
+ l.verbose("Optimize with r.js with uRequire's 'build.js' = ", l.prettify(_.omit(rjsConfig, ['wrap'])));
+ this.requirejs.optimize(_.clone(rjsConfig), function(buildResponse) {
+ return l.verbose('r.js buildResponse = ', buildResponse);
+ });
+ return setTimeout((function() {
+ l.debug(60, 'Checking r.js output file...');
+ if (_fs.existsSync(build.combinedFile)) {
+ l.verbose("Combined file '" + build.combinedFile + "' written successfully.");
+ if (Logger.prototype.debugLevel < 50) {
+ l.debug(40, "Deleting temporary directory '" + build.outputPath + "'.");
+ _wrench.rmdirSyncRecursive(build.outputPath);
+ } else {
+ l.debug("NOT Deleting temporary directory '" + build.outputPath + "', due to debugLevel >= 50.");
+ }
+ return build.done(true);
+ } else {
+ l.err("Combined file '" + build.combinedFile + "' NOT written.\"\n\n Some remedy:\n\n a) Is your *bundle.main = '" + _this.main + "'* or *bundle.bundleName = '" + _this.bundleName + "'* properly defined ?\n - 'main' should refer to your 'entry' module, that requires all other modules - if not defined, it defaults to 'bundleName'.\n - 'bundleName' is what 'main' defaults to, if its a module.\n\n b) Perhaps you have a missing dependcency ?\n r.js doesn't like this at all, but it wont tell you unless logLevel is set to error/trace, which then halts execution.\n\n c) Re-run uRequire with debugLevel >=90, to enable r.js's logLevel:0 (trace).\n *Note this prevents uRequire from finishing properly / printing this message!*\n\n Note that you can check the AMD-ish files used in temporary directory '" + build.outputPath + "'.\n\n More remedy on the way... till then, you can try running r.js optimizer your self, based on the following build.js: \u001b[0m\n " + (l.prettify(rjsConfig)));
+ return build.done(false);
+ }
+ }), 100);
+ }
+ };
+
+ /*
+ Gets dependencies & the variables (they bind with), througout this bundle.
+
+ The information is gathered from all modules and joined together.
+
+ Also it uses bundle.dependencies.variableNames, if some dep has no corresponding vars [].
+
+ @param {Object} q optional query with two optional fields : depType & depName
+
+ @return {dependencies.variableNames} `dependency: ['var1', 'var2']` eg
+ {
+ 'underscore': '_'
+ 'jquery': ["$", "jQuery"]
+ 'models/PersonModel': ['persons', 'personsModel']
+ }
+ */
+
+
+ Bundle.prototype.getDepsVars = function(q) {
+ var depsAndVars, gatherDepsVars, uMK, uModule, variableNames, vn, _ref1, _ref2;
+ depsAndVars = {};
+ gatherDepsVars = function(depsVars) {
+ var dep, dv, v, vars, _results;
+ _results = [];
+ for (dep in depsVars) {
+ vars = depsVars[dep];
+ dv = (depsAndVars[dep] || (depsAndVars[dep] = []));
+ _results.push((function() {
+ var _i, _len, _results1;
+ _results1 = [];
+ for (_i = 0, _len = vars.length; _i < _len; _i++) {
+ v = vars[_i];
+ if (__indexOf.call(dv, v) < 0) {
+ _results1.push(dv.push(v));
+ }
+ }
+ return _results1;
+ })());
+ }
+ return _results;
+ };
+ _ref1 = this.uModules;
+ for (uMK in _ref1) {
+ uModule = _ref1[uMK];
+ gatherDepsVars(uModule.getDepsAndVars(q));
+ }
+ if (variableNames = (_ref2 = this.dependencies) != null ? _ref2.variableNames : void 0) {
+ vn = _B.go(variableNames, {
+ fltr: function(v, k) {
+ return (depsAndVars[k] !== void 0) && _.isEmpty(depsAndVars[k]);
+ }
+ });
+ if (!_.isEmpty(vn)) {
+ l.warn("\n Had to pick from variableNames for some deps = \n", vn);
+ }
+ gatherDepsVars(vn);
+ }
+ return depsAndVars;
+ };
+
+ return Bundle;
+
+}).call(this, BundleBase);
+
+if (Logger.prototype.debugLevel > 90) {
+ YADC = require('YouAreDaChef').YouAreDaChef;
+ YADC(Bundle).before(/_constructor/, function(match, bundleCfg) {
+ return l.debug("Before '" + match + "' with bundleCfg = \n", _.omit(bundleCfg, []));
+ }).before(/combine/, function(match) {
+ return l.debug('combine: optimizing with r.js');
+ });
+}
+
+module.exports = Bundle;
View
119 build/code/process/BundleBase.js
@@ -0,0 +1,119 @@
+// Generated by CoffeeScript 1.4.0
+var BundleBase, Dependency, Logger, l, pathRelative, upath, _, _fs;
+
+_ = require('lodash');
+
+_fs = require('fs');
+
+upath = require('../paths/upath');
+
+pathRelative = require('../paths/pathRelative');
+
+Dependency = require('../Dependency');
+
+Logger = require('../utils/Logger');
+
+l = new Logger('NodeRequirer');
+
+/*
+Common functionality used at build time (Bundle) or runtime (NodeRequirer)
+*/
+
+
+BundleBase = (function() {
+ var _this = this;
+
+ Function.prototype.property = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(this.prototype, n, d));
+ }
+ return _results;
+ };
+
+ Function.prototype.staticProperty = function(p) {
+ var d, n, _results;
+ _results = [];
+ for (n in p) {
+ d = p[n];
+ _results.push(Object.defineProperty(BundleBase.prototype, n, d));
+ }
+ return _results;
+ };
+
+ function BundleBase() {
+ this._constructor.apply(this, arguments);
+ }
+
+ BundleBase.property({
+ webRoot: {
+ get: function() {
+ return upath.normalize("" + (this.webRootMap[0] === '.' ? this.bundlePath + '/' + this.webRootMap : this.webRootMap));
+ }
+ }
+ });
+
+ /*
+ For a given `Dependency`, resolve *all possible* paths to the file.
+
+ `resolvePaths` is respecting:
+ - The `Dependency`'s own semantics, eg `webRootMap` if `dep` is relative to web root (i.e starts with `\`) and similarly for isRelative etc. See <code>Dependency</code>
+ - `@relativeTo` param, which defaults to the module file calling `require` (ie. @dirname), but can be anything eg. @bundlePath.
+ - `requirejs` config, if it exists in this instance of BundleBase / NodeRequirer
+
+ @param {Dependency} dep The Dependency instance whose paths we are resolving.
+ @param {String} relativeTo Resolve relative to this path. Default is `@dirname`, i.e the module/file that called `require`
+
+ @return {Array<String>} The resolved paths of the Dependency
+ */
+
+
+ BundleBase.prototype.resolvePaths = function(dep, relativeTo) {
+ var addit, depName, path, pathStart, paths, resPaths, _i, _len, _ref;
+ if (relativeTo == null) {
+ relativeTo = this.dirname;
+ }
+ depName = dep.name({
+ plugin: false,
+ ext: true
+ });
+ resPaths = [];
+ addit = function(path) {
+ return resPaths.push(upath.normalize(path));
+ };
+ if (dep.isFileRelative()) {
+ addit(relativeTo + '/' + depName);
+ } else {
+ if (dep.isWebRootMap()) {
+ addit(this.webRoot + depName);
+ } else {
+ pathStart = depName.split('/')[0];
+ if ((_ref = this.getRequireJSConfig().paths) != null ? _ref[pathStart] : void 0) {
+ paths = this.getRequireJSConfig().paths[pathStart];
+ if (!_(paths).isArray()) {
+ paths = [paths];
+ }
+ for (_i = 0, _len = paths.length; _i < _len; _i++) {
+ path = paths[_i];
+ addit(this.bundlePath + (depName.replace(pathStart, path)));
+ }
+ } else {
+ if (dep.isRelative()) {
+ addit(this.bundlePath + depName);
+ } else {
+ addit(depName);
+ addit(this.bundlePath + d