diff --git a/lib/stitch.js b/lib/stitch.js index 967fb2b..91a38e4 100644 --- a/lib/stitch.js +++ b/lib/stitch.js @@ -1,6 +1,8 @@ +// Generated by CoffeeScript 1.4.0 (function() { - var CoffeeScript, Package, async, compilers, eco, extname, fs, join, normalize, _, _ref; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + var CoffeeScript, Package, async, compilers, eco, extname, fs, isWindows, join, normalize, _, _ref, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __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('underscore'); @@ -48,16 +50,22 @@ } + isWindows = process.platform === "win32"; + exports.Package = Package = (function() { function Package(config) { this.compileSources = __bind(this.compileSources, this); + this.compileDependencies = __bind(this.compileDependencies, this); - var _ref2, _ref3, _ref4, _ref5; - this.identifier = (_ref2 = config.identifier) != null ? _ref2 : 'require'; - this.paths = (_ref3 = config.paths) != null ? _ref3 : ['lib']; - this.dependencies = (_ref4 = config.dependencies) != null ? _ref4 : []; + + var _ref1, _ref2, _ref3, _ref4, _ref5; + this.rootModuleName = config.rootModuleName; + this.identifier = (_ref1 = config.identifier) != null ? _ref1 : 'require'; + this.paths = (_ref2 = config.paths) != null ? _ref2 : ['lib']; + this.dependencies = (_ref3 = config.dependencies) != null ? _ref3 : []; this.compilers = _.extend({}, compilers, config.compilers); + this.excludes = (_ref4 = config.excludes) != null ? _ref4 : []; this.cache = (_ref5 = config.cache) != null ? _ref5 : true; this.mtimeCache = {}; this.compileCache = {}; @@ -87,12 +95,14 @@ Package.prototype.compileSources = function(callback) { var _this = this; return async.reduce(this.paths, {}, _.bind(this.gatherSourcesFromPath, this), function(err, sources) { - var filename, index, name, result, source, _ref2; - if (err) return callback(err); - result = "(function(/*! Stitch !*/) {\n if (!this." + _this.identifier + ") {\n var modules = {}, cache = {}, require = function(name, root) {\n var path = expand(root, name), module = cache[path], fn;\n if (module) {\n return module.exports;\n } else if (fn = modules[path] || modules[path = expand(path, './index')]) {\n module = {id: path, exports: {}};\n try {\n cache[path] = module;\n fn(module.exports, function(name) {\n return require(name, dirname(path));\n }, module);\n return module.exports;\n } catch (err) {\n delete cache[path];\n throw err;\n }\n } else {\n throw 'module \\'' + name + '\\' not found';\n }\n }, expand = function(root, name) {\n var results = [], parts, part;\n if (/^\\.\\.?(\\/|$)/.test(name)) {\n parts = [root, name].join('/').split('/');\n } else {\n parts = name.split('/');\n }\n for (var i = 0, length = parts.length; i < length; i++) {\n part = parts[i];\n if (part == '..') {\n results.pop();\n } else if (part != '.' && part != '') {\n results.push(part);\n }\n }\n return results.join('/');\n }, dirname = function(path) {\n return path.split('/').slice(0, -1).join('/');\n };\n this." + _this.identifier + " = function(name) {\n return require(name, '');\n }\n this." + _this.identifier + ".define = function(bundle) {\n for (var key in bundle)\n modules[key] = bundle[key];\n };\n }\n return this." + _this.identifier + ".define;\n}).call(this)({"; + var filename, index, name, result, source, _ref1; + if (err) { + return callback(err); + } + result = "(function(/*! Stitch !*/) {\n\n var modules = {}, cache = {}, req = function(name, root) {\n var path = expand(root, name), module = cache[path], fn;\n if (module) {\n return module.exports;\n } else if (fn = modules[path] || modules[path = expand(path, './index')]) {\n module = {id: path, exports: {}};\n try {\n cache[path] = module;\n fn(module.exports, function(name) {\n return req(name, dirname(path));\n }, module);\n return module.exports;\n } catch (err) {\n delete cache[path];\n throw err;\n }\n } else {\n throw 'module \\'' + name + '\\' not found';\n }\n }, expand = function(root, name) {\n var results = [], parts, part;\n if (/^\\.\\.?(\\/|$)/.test(name)) {\n parts = [root, name].join('/').split('/');\n } else {\n parts = name.split('/');\n }\n for (var i = 0, length = parts.length; i < length; i++) {\n part = parts[i];\n if (part == '..') {\n results.pop();\n } else if (part != '.' && part != '') {\n results.push(part);\n }\n }\n return results.join('/');\n }, dirname = function(path) {\n return path.split('/').slice(0, -1).join('/');\n };\n\n return function(bundle) {\n for (var key in bundle){\n modules[key] = bundle[key];\n }\n\n //UMD\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as a named module\n define([],function(){\n return req('" + _this.rootModuleName + "','');\n });\n } else {\n // Browser globals\n this." + _this.rootModuleName + " = req('" + _this.rootModuleName + "','');\n\n //define global require\n if (!this." + _this.identifier + ") {\n this." + _this.identifier + " = function(name) {\n return req(name, '');\n }\n }\n }\n };\n}).call(this)({"; index = 0; for (name in sources) { - _ref2 = sources[name], filename = _ref2.filename, source = _ref2.source; + _ref1 = sources[name], filename = _ref1.filename, source = _ref1.source; result += index++ === 0 ? "" : ", "; result += JSON.stringify(name); result += ": function(exports, require, module) {" + source + "}"; @@ -127,10 +137,14 @@ Package.prototype.gatherSourcesFromPath = function(sources, sourcePath, callback) { var _this = this; return fs.stat(sourcePath, function(err, stat) { - if (err) return callback(err); + if (err) { + return callback(err); + } if (stat.isDirectory()) { return _this.getFilesInTree(sourcePath, function(err, paths) { - if (err) return callback(err); + if (err) { + return callback(err); + } return async.reduce(paths, sources, _.bind(_this.gatherCompilableSource, _this), callback); }); } else { @@ -143,7 +157,9 @@ var _this = this; if (this.compilers[extname(path).slice(1)]) { return this.getRelativePath(path, function(err, relativePath) { - if (err) return callback(err); + if (err) { + return callback(err); + } return _this.compileFile(path, function(err, source) { var extension, key; if (err) { @@ -167,15 +183,23 @@ Package.prototype.getRelativePath = function(path, callback) { var _this = this; return fs.realpath(path, function(err, sourcePath) { - if (err) return callback(err); + if (err) { + return callback(err); + } return async.map(_this.paths, fs.realpath, function(err, expandedPaths) { - var base, expandedPath, _i, _len; - if (err) return callback(err); + var base, expandedPath, sp, _i, _len; + if (err) { + return callback(err); + } for (_i = 0, _len = expandedPaths.length; _i < _len; _i++) { expandedPath = expandedPaths[_i]; - base = expandedPath + "/"; + base = expandedPath + (isWindows ? "\\" : "/"); if (sourcePath.indexOf(base) === 0) { - return callback(null, sourcePath.slice(base.length)); + sp = sourcePath.slice(base.length); + if (isWindows) { + sp = sp.replace(/\\/g, "/"); + } + return callback(null, sp); } } return callback(new Error("" + path + " isn't in the require path")); @@ -220,14 +244,18 @@ Package.prototype.walkTree = function(directory, callback) { var _this = this; return fs.readdir(directory, function(err, files) { - if (err) return callback(err); + if (err) { + return callback(err); + } return async.forEach(files, function(file, next) { var filename; - if (file.match(/^\./)) return next(); filename = join(directory, file); + if ((__indexOf.call(_this.excludes, filename) >= 0) || file.match(/^\./)) { + return next(); + } return fs.stat(filename, function(err, stats) { - var _ref2; - _this.mtimeCache[filename] = stats != null ? (_ref2 = stats.mtime) != null ? _ref2.toString() : void 0 : void 0; + var _ref1; + _this.mtimeCache[filename] = stats != null ? (_ref1 = stats.mtime) != null ? _ref1.toString() : void 0 : void 0; if (!err && stats.isDirectory()) { return _this.walkTree(filename, function(err, filename) { if (filename) { diff --git a/src/stitch.coffee b/src/stitch.coffee index cecca07..4d99e3f 100644 --- a/src/stitch.coffee +++ b/src/stitch.coffee @@ -28,13 +28,16 @@ try module._compile content, filename catch err +isWindows = process.platform is "win32" exports.Package = class Package constructor: (config) -> + @rootModuleName = config.rootModuleName @identifier = config.identifier ? 'require' @paths = config.paths ? ['lib'] @dependencies = config.dependencies ? [] @compilers = _.extend {}, compilers, config.compilers + @excludes = config.excludes ? [] @cache = config.cache ? true @mtimeCache = {} @@ -59,54 +62,69 @@ exports.Package = class Package result = """ (function(/*! Stitch !*/) { - if (!this.#{@identifier}) { - var modules = {}, cache = {}, require = function(name, root) { - var path = expand(root, name), module = cache[path], fn; - if (module) { + + var modules = {}, cache = {}, req = function(name, root) { + var path = expand(root, name), module = cache[path], fn; + if (module) { + return module.exports; + } else if (fn = modules[path] || modules[path = expand(path, './index')]) { + module = {id: path, exports: {}}; + try { + cache[path] = module; + fn(module.exports, function(name) { + return req(name, dirname(path)); + }, module); return module.exports; - } else if (fn = modules[path] || modules[path = expand(path, './index')]) { - module = {id: path, exports: {}}; - try { - cache[path] = module; - fn(module.exports, function(name) { - return require(name, dirname(path)); - }, module); - return module.exports; - } catch (err) { - delete cache[path]; - throw err; - } - } else { - throw 'module \\'' + name + '\\' not found'; + } catch (err) { + delete cache[path]; + throw err; } - }, expand = function(root, name) { - var results = [], parts, part; - if (/^\\.\\.?(\\/|$)/.test(name)) { - parts = [root, name].join('/').split('/'); - } else { - parts = name.split('/'); + } else { + throw 'module \\'' + name + '\\' not found'; + } + }, expand = function(root, name) { + var results = [], parts, part; + if (/^\\.\\.?(\\/|$)/.test(name)) { + parts = [root, name].join('/').split('/'); + } else { + parts = name.split('/'); + } + for (var i = 0, length = parts.length; i < length; i++) { + part = parts[i]; + if (part == '..') { + results.pop(); + } else if (part != '.' && part != '') { + results.push(part); } - for (var i = 0, length = parts.length; i < length; i++) { - part = parts[i]; - if (part == '..') { - results.pop(); - } else if (part != '.' && part != '') { - results.push(part); + } + return results.join('/'); + }, dirname = function(path) { + return path.split('/').slice(0, -1).join('/'); + }; + + return function(bundle) { + for (var key in bundle){ + modules[key] = bundle[key]; + } + + //UMD + if (typeof define === 'function' && define.amd) { + // AMD. Register as a named module + define([],function(){ + return req('#{@rootModuleName}',''); + }); + } else { + // Browser globals + this.#{@rootModuleName} = req('#{@rootModuleName}',''); + + //define global require + if (!this.#{@identifier}) { + this.#{@identifier} = function(name) { + return req(name, ''); } } - return results.join('/'); - }, dirname = function(path) { - return path.split('/').slice(0, -1).join('/'); - }; - this.#{@identifier} = function(name) { - return require(name, ''); } - this.#{@identifier}.define = function(bundle) { - for (var key in bundle) - modules[key] = bundle[key]; - }; - } - return this.#{@identifier}.define; + }; }).call(this)({ """ @@ -171,9 +189,11 @@ exports.Package = class Package return callback err if err for expandedPath in expandedPaths - base = expandedPath + "/" + base = expandedPath + (if isWindows then "\\" else "/") if sourcePath.indexOf(base) is 0 - return callback null, sourcePath.slice base.length + sp = sourcePath.slice base.length + if isWindows then sp = sp.replace /\\/g, "/" #replace backslashes with forward slashes + return callback null,sp callback new Error "#{path} isn't in the require path" compileFile: (path, callback) -> @@ -208,8 +228,8 @@ exports.Package = class Package return callback err if err async.forEach files, (file, next) => - return next() if file.match /^\./ filename = join directory, file + return next() if (filename in @excludes) or file.match /^\./ fs.stat filename, (err, stats) => @mtimeCache[filename] = stats?.mtime?.toString()