├── .gitignore ├── .npmignore ├── History.md ├── README.md ├── bin └── browserbuild ├── examples ├── dir │ ├── a.js │ └── b.js ├── file.js ├── instrument.js └── node-only.js ├── lib ├── browserbuild.js └── require.js ├── package.json └── support └── debug ├── .gitignore ├── .npmignore ├── History.md ├── Makefile ├── Readme.md ├── debug.js ├── example ├── app.js ├── browser.html ├── wildcards.js └── worker.js ├── index.js ├── lib └── debug.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | examples 2 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.7.0 / 2013-05-29 3 | ================== 4 | 5 | * added support for `.json`. files 6 | 7 | 0.6.0 / 2012-10-14 8 | ================== 9 | 10 | * added support for `module.exports` 11 | * sort files by name before building. [mixu] 12 | 13 | 0.5.0 / 2012-07-07 14 | ================== 15 | 16 | * Allow for multiple basepaths, separated by a comma. [slaskis] 17 | 18 | 0.4.8 / 2012-04-03 19 | ================== 20 | 21 | * Added debug repository directly to avoid NPM dependency conflicts. 22 | 23 | 0.4.7 / 2012-04-03 24 | ================== 25 | 26 | * Specified visionmedia/debug version. 27 | 28 | 0.4.6 / 2012-04-02 29 | ================== 30 | 31 | * Added parent information to require errors [visionmedia] 32 | 33 | 0.4.5 / 2012-03-25 34 | ================== 35 | 36 | * Fixed directory traversing. [Sembiance] 37 | 38 | 0.4.4 / 2012-03-25 39 | ================== 40 | 41 | * Added back `// if node` support. [Sembiance] 42 | * Leveraged visionmedia/debug. 43 | 44 | 0.4.3 / 2012-03-20 45 | ================== 46 | 47 | * Added support for `require('debug')` transparently. 48 | 49 | 0.4.2 / 2012-03-20 50 | ================== 51 | 52 | * Fixed debug() interface when debugging is disabled. 53 | 54 | 0.4.1 / 2012-03-20 55 | ================== 56 | 57 | * Avoid whitespace strip for visionmedia/debug 58 | 59 | 0.4.0 / 2012-03-20 60 | ================== 61 | 62 | * Outputs to stdout instead of `dist/`. 63 | * Instrumentation removed in favor of visionmedia/debug. 64 | * Accepts a list of files instead of a single directory. 65 | * Cleaned up README 66 | 67 | 0.3.1 / 2012-03-09 68 | ================== 69 | 70 | * Removed test for validity of global. 71 | 72 | 0.3.0 / 2012-01-18 73 | ================== 74 | 75 | * Added support for `global` pointing to the global object, generally 76 | `window`. 77 | 78 | 0.2.1 / 2012-01-16 79 | ================== 80 | 81 | * Fixed double quotes in debug statements. 82 | 83 | 0.2.0 / 2011-12-21 84 | ================== 85 | 86 | * Added debugging instrumentatiion functionality (`-i`). 87 | 88 | 0.1.1 / 2011-12-15 89 | ================== 90 | 91 | * Added example for node-only code that gets removed for the build. 92 | * Added support for `// if node` 93 | * Fixed `bin` in package.json 94 | * Corrected credits. 95 | * Initial release. 96 | 97 | 0.1.0 / 2011-11-18 98 | ================== 99 | 100 | * Initial release. 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repository is no longer maintained 2 | 3 | # Browserbuild 4 | 5 | Browserbuild allows you to write code for the browser that leverages 6 | `require`, `module` and `exports`, but that gets exposed as a global. 7 | 8 | It doesn't enforce any script loaders on the user to leverage the 9 | compiled library. 10 | 11 | ## Example 12 | 13 | 1. Write for Node 14 | 15 | **lib/hithere.js** 16 | 17 | ```js 18 | var b = require('./b') 19 | 20 | module.exports = function () { 21 | alert('hello ' + b()); 22 | } 23 | ``` 24 | 25 | **lib/b.js** 26 | 27 | ``` 28 | module.exports = function () { 29 | return 'world'; 30 | } 31 | ``` 32 | 33 | 2. Build for browser! 34 | 35 | ```bash 36 | $ browserbuild -m hithere -b lib/ `find lib -name '*.js'` > my-library.js 37 | ``` 38 | 39 | 3. Use! 40 | 41 | ```html 42 | 43 | 46 | ``` 47 | 48 | ## Features 49 | 50 | - Write code like you would write for Node.JS. 51 | - No wrappers 52 | - No `undefined` type checking for `module` or `window`. 53 | - No new patterns 54 | - No AMD, no `require.async`, no CommonJS transport proposals. 55 | - Doesn't depend on `require` implementations on the client. 56 | - It exposes your module as a single global, like `jQuery`, `io`, `_`. Just 57 | like everyone is used to. 58 | - No code bloat. 59 | - The conversion for the browser only adds a few lines of code. 60 | - No trouble debugging. 61 | - [debug](http://github.com/visionmedia/debug) integration 62 | - Make dev builds with debugging enabled. 63 | 64 | ## Credits 65 | 66 | - `require` functions by [Jonah Fox](https://github.com/weepy), with 67 | modifications by TJ Holowaychuk <tj@learnboost.com> 68 | - inspired by `browserify` 69 | 70 | ## License 71 | 72 | (The MIT License) 73 | 74 | Copyright (c) 2011 Guillermo Rauch <guillermo@learnboost.com> 75 | 76 | Permission is hereby granted, free of charge, to any person obtaining 77 | a copy of this software and associated documentation files (the 78 | 'Software'), to deal in the Software without restriction, including 79 | without limitation the rights to use, copy, modify, merge, publish, 80 | distribute, sublicense, and/or sell copies of the Software, and to 81 | permit persons to whom the Software is furnished to do so, subject to 82 | the following conditions: 83 | 84 | The above copyright notice and this permission notice shall be 85 | included in all copies or substantial portions of the Software. 86 | 87 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 88 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 89 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 90 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 91 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 92 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 93 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 94 | -------------------------------------------------------------------------------- /bin/browserbuild: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var program = require('commander') 4 | , pwd = process.cwd() 5 | , browserbuild = require('../lib/browserbuild.js') 6 | , list = function(v){return v.split(/ *, */)} 7 | 8 | // program 9 | 10 | program 11 | .version(require('../package').version) 12 | .usage('[options] ') 13 | .option('-g, --global [name]', 'Name of the global to export.') 14 | .option('-b, --basepath [paths]', 'List of base paths of supplied files ['+ pwd + '].', list, [pwd]) 15 | .option('-m, --main ', 'Name of the main file/module to export.') 16 | .option('-d, --debug', 'Includes visionmedia/debug for a dev build.') 17 | .parse(process.argv) 18 | 19 | // validate 20 | 21 | if (!program.main) { 22 | console.error('\n Please supply a `main` option\n'); 23 | return; 24 | } 25 | 26 | if (!program.args.length) { 27 | console.error('\n Please supply files.\n'); 28 | return; 29 | } 30 | 31 | // process arguments 32 | 33 | browserbuild(program.args, program) 34 | .render(function (err, txt) { 35 | console.log(txt); 36 | }); 37 | -------------------------------------------------------------------------------- /examples/dir/a.js: -------------------------------------------------------------------------------- 1 | 2 | var b = require('./b'); 3 | 4 | exports.hello = 'world'; 5 | exports.a = b; 6 | -------------------------------------------------------------------------------- /examples/dir/b.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = 'woot'; 3 | -------------------------------------------------------------------------------- /examples/file.js: -------------------------------------------------------------------------------- 1 | exports.a = 'b'; 2 | -------------------------------------------------------------------------------- /examples/instrument.js: -------------------------------------------------------------------------------- 1 | 2 | // debug: test 3 | 4 | // assert: module, "Module present" 5 | 6 | var i = 'An example of'; 7 | 8 | // $start: i + " expression prolifing" 9 | 10 | // $end: i + " expression profiling" 11 | -------------------------------------------------------------------------------- /examples/node-only.js: -------------------------------------------------------------------------------- 1 | 2 | // if node 3 | process.exit(1); 4 | // end 5 | 6 | console.log('browser and node'); 7 | -------------------------------------------------------------------------------- /lib/browserbuild.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | path = require('path'), 3 | debug = require('debug')('browserbuild'); 4 | 5 | // source for client-side require 6 | var requireCode = fs.readFileSync(__dirname + '/require.js', 'utf8') 7 | .replace(/\/*([^/]+)\/\n/g, '') 8 | .replace(/\n/g, '') 9 | .replace(/ +/g, ' '); 10 | 11 | var debugCode = fs.readFileSync(__dirname + '/../support/debug/debug.js', 'utf8'); 12 | 13 | function Renderer(options) { 14 | this.options = options || {}; 15 | this.paths = []; 16 | }; 17 | 18 | Renderer.prototype.set = function(key, val){ 19 | this.options[key] = val; 20 | return this; 21 | }; 22 | 23 | Renderer.prototype.include = function(filepath){ 24 | if(!filepath) return this; 25 | var self = this, 26 | paths = (Array.isArray(filepath) ? filepath : [ filepath ]); 27 | 28 | paths.forEach(function(p) { 29 | var isDirectory = fs.statSync(p).isDirectory(); 30 | if (isDirectory) { 31 | return fs.readdirSync(p).forEach(function (f) { 32 | self.include(p + '/' + f); 33 | }); 34 | } 35 | self.paths.push(p); 36 | }); 37 | return this; 38 | }; 39 | 40 | Renderer.prototype.render = function(done){ 41 | if(!done) return this; 42 | var self = this, 43 | opt = this.options, 44 | mod = path.basename(opt.main); 45 | 46 | var data = '(function(){' 47 | + 'var global = this;' 48 | + (opt.debug ? debugCode : 'function debug(){return debug};') 49 | + requireCode 50 | + this.paths.sort().reduce(function(str, path) { 51 | return str + self._render(path); 52 | }, '') 53 | + 'var exp = require(\'' + mod + '\');' 54 | + 'if ("undefined" != typeof module) module.exports = exp;' 55 | + 'else ' + (opt.global || opt.main) + ' = exp;\n' 56 | + '})();'; 57 | 58 | done(undefined, data); 59 | }; 60 | 61 | Renderer.prototype._render = function(filepath) { 62 | var basepath = this.options.basepath 63 | , source = fs.readFileSync(filepath, 'utf8') 64 | 65 | // match a basepath 66 | basepath.some(function(base){ 67 | if (base == filepath.substr(0, base.length)) { 68 | filepath = filepath.substr(base.length); 69 | return true; 70 | } 71 | }) 72 | 73 | if (/\.json$/.test(filepath)) { 74 | // JSON file 75 | source = 'module.exports = '+source; 76 | } 77 | else { 78 | // remove `if node` 79 | var ignoring = false 80 | 81 | source = source.split('\n').map(function (line, i) { 82 | if (ignoring) { 83 | if (/^ *\/\/ *end/.test(line)) { 84 | ignoring = false; 85 | } 86 | return ''; 87 | } else { 88 | if (/^ *\/\/ *if *node/.test(line)) { 89 | debug('[%s] skipping node-only code at line %d' 90 | , path.basename(filepath), i + 1); 91 | ignoring = true; 92 | return ''; 93 | } else { 94 | return line; 95 | } 96 | } 97 | }).join('\n'); 98 | } 99 | 100 | // wrap 101 | return 'require.register("' + filepath + '", ' 102 | + 'function(module, exports, require, global){\n' + source + '\n});'; 103 | }; 104 | 105 | function render(paths, options, fn) { 106 | if ('function' == typeof options) fn = options, options = {}; 107 | return new Renderer(options).include(paths).render(fn); 108 | }; 109 | 110 | // e.g. browserbuild(paths, options).set(key, val).include(paths).render(fn) 111 | exports = module.exports = render; 112 | // e.g. browserbuild.render(paths, options, fn) 113 | exports.render = render; 114 | -------------------------------------------------------------------------------- /lib/require.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Require functions by TJ Holowaychuk 4 | */ 5 | 6 | /** 7 | * Require the given path. 8 | * 9 | * @param {String} path 10 | * @return {Object} exports 11 | * @api public 12 | */ 13 | 14 | function require(p, parent){ 15 | var path = require.resolve(p) 16 | , mod = require.modules[path]; 17 | if (!mod) throw new Error('failed to require "' + p + '" from ' + parent); 18 | if (!mod.exports) { 19 | mod.exports = {}; 20 | mod.call(mod.exports, mod, mod.exports, require.relative(path), global); 21 | } 22 | return mod.exports; 23 | } 24 | 25 | /** 26 | * Registered modules. 27 | */ 28 | 29 | require.modules = {}; 30 | 31 | /** 32 | * Resolve `path`. 33 | * 34 | * @param {String} path 35 | * @return {Object} module 36 | * @api public 37 | */ 38 | 39 | require.resolve = function(path){ 40 | var orig = path 41 | , reg = path + '.js' 42 | , index = path + '/index.js'; 43 | return require.modules[reg] && reg 44 | || require.modules[index] && index 45 | || orig; 46 | }; 47 | 48 | /** 49 | * Register module at `path` with callback `fn`. 50 | * 51 | * @param {String} path 52 | * @param {Function} fn 53 | * @api public 54 | */ 55 | 56 | require.register = function(path, fn){ 57 | require.modules[path] = fn; 58 | }; 59 | 60 | /** 61 | * Return a require function relative to the `parent` path. 62 | * 63 | * @param {String} parent 64 | * @return {Function} 65 | * @api private 66 | */ 67 | 68 | require.relative = function(parent) { 69 | return function(p){ 70 | if ('debug' == p) return debug; 71 | if ('.' != p.charAt(0)) return require(p); 72 | 73 | var path = parent.split('/') 74 | , segs = p.split('/'); 75 | path.pop(); 76 | 77 | for (var i = 0; i < segs.length; i++) { 78 | var seg = segs[i]; 79 | if ('..' == seg) path.pop(); 80 | else if ('.' != seg) path.push(seg); 81 | } 82 | 83 | return require(path.join('/'), parent); 84 | }; 85 | }; 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browserbuild" 3 | , "version": "0.7.0" 4 | , "bin": { "browserbuild": "./bin/browserbuild" } 5 | , "main": "./lib/browserbuild.js" 6 | , "dependencies": { 7 | "commander": "0.5.x" 8 | , "debug": "0.6.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /support/debug/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | *.sock 4 | -------------------------------------------------------------------------------- /support/debug/.npmignore: -------------------------------------------------------------------------------- 1 | support 2 | test 3 | examples 4 | *.sock 5 | -------------------------------------------------------------------------------- /support/debug/History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.6.0 / 2012-03-16 3 | ================== 4 | 5 | * Added support for "-" prefix in DEBUG [Vinay Pulim] 6 | * Added `.enabled` flag to the node version [TooTallNate] 7 | 8 | 0.5.0 / 2012-02-02 9 | ================== 10 | 11 | * Added: humanize diffs. Closes #8 12 | * Added `debug.disable()` to the CS variant 13 | * Removed padding. Closes #10 14 | * Fixed: persist client-side variant again. Closes #9 15 | 16 | 0.4.0 / 2012-02-01 17 | ================== 18 | 19 | * Added browser variant support for older browsers [TooTallNate] 20 | * Added `debug.enable('project:*')` to browser variant [TooTallNate] 21 | * Added padding to diff (moved it to the right) 22 | 23 | 0.3.0 / 2012-01-26 24 | ================== 25 | 26 | * Added millisecond diff when isatty, otherwise UTC string 27 | 28 | 0.2.0 / 2012-01-22 29 | ================== 30 | 31 | * Added wildcard support 32 | 33 | 0.1.0 / 2011-12-02 34 | ================== 35 | 36 | * Added: remove colors unless stderr isatty [TooTallNate] 37 | 38 | 0.0.1 / 2010-01-03 39 | ================== 40 | 41 | * Initial release 42 | -------------------------------------------------------------------------------- /support/debug/Makefile: -------------------------------------------------------------------------------- 1 | 2 | test: 3 | @echo "populate me" 4 | 5 | .PHONY: test -------------------------------------------------------------------------------- /support/debug/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # debug 3 | 4 | tiny node.js debugging utility. 5 | 6 | ## Installation 7 | 8 | ``` 9 | $ npm install debug 10 | ``` 11 | 12 | ## Example 13 | 14 | This module is modelled after node core's debugging technique, allowing you to enable one or more topic-specific debugging functions, for example core does the following within many modules: 15 | 16 | ```js 17 | var debug; 18 | if (process.env.NODE_DEBUG && /cluster/.test(process.env.NODE_DEBUG)) { 19 | debug = function(x) { 20 | var prefix = process.pid + ',' + 21 | (process.env.NODE_WORKER_ID ? 'Worker' : 'Master'); 22 | console.error(prefix, x); 23 | }; 24 | } else { 25 | debug = function() { }; 26 | } 27 | ``` 28 | 29 | This concept is extremely simple but it works well. With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility. 30 | 31 | Example _app.js_: 32 | 33 | ```js 34 | var debug = require('debug')('http') 35 | , http = require('http') 36 | , name = 'My App'; 37 | 38 | // fake app 39 | 40 | debug('booting %s', name); 41 | 42 | http.createServer(function(req, res){ 43 | debug(req.method + ' ' + req.url); 44 | res.end('hello\n'); 45 | }).listen(3000, function(){ 46 | debug('listening'); 47 | }); 48 | 49 | // fake worker of some kind 50 | 51 | require('./worker'); 52 | ``` 53 | 54 | Example _worker.js_: 55 | 56 | ```js 57 | var debug = require('debug')('worker'); 58 | 59 | setInterval(function(){ 60 | debug('doing some work'); 61 | }, 1000); 62 | ``` 63 | 64 | The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: 65 | 66 | ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png) 67 | 68 | ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png) 69 | 70 | ## Millisecond diff 71 | 72 | When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. 73 | 74 | ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png) 75 | 76 | When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below: 77 | 78 | ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png) 79 | 80 | ## Conventions 81 | 82 | If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". 83 | 84 | ## Wildcards 85 | 86 | The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. 87 | 88 | You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:". 89 | 90 | ## Browser support 91 | 92 | Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. 93 | 94 | ```js 95 | a = debug('worker:a'); 96 | b = debug('worker:b'); 97 | 98 | setInterval(function(){ 99 | a('doing some work'); 100 | }, 1000); 101 | 102 | setInterval(function(){ 103 | a('doing some work'); 104 | }, 1200); 105 | ``` 106 | 107 | ## License 108 | 109 | (The MIT License) 110 | 111 | Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> 112 | 113 | Permission is hereby granted, free of charge, to any person obtaining 114 | a copy of this software and associated documentation files (the 115 | 'Software'), to deal in the Software without restriction, including 116 | without limitation the rights to use, copy, modify, merge, publish, 117 | distribute, sublicense, and/or sell copies of the Software, and to 118 | permit persons to whom the Software is furnished to do so, subject to 119 | the following conditions: 120 | 121 | The above copyright notice and this permission notice shall be 122 | included in all copies or substantial portions of the Software. 123 | 124 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 125 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 126 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 127 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 128 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 129 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 130 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /support/debug/debug.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * debug 4 | * Copyright(c) 2012 TJ Holowaychuk 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Create a debugger with the given `name`. 10 | * 11 | * @param {String} name 12 | * @return {Type} 13 | * @api public 14 | */ 15 | 16 | function debug(name) { 17 | if (!debug.enabled(name)) return function(){}; 18 | 19 | return function(fmt){ 20 | var curr = new Date; 21 | var ms = curr - (debug[name] || curr); 22 | debug[name] = curr; 23 | 24 | fmt = name 25 | + ' ' 26 | + fmt 27 | + ' +' + debug.humanize(ms); 28 | 29 | // This hackery is required for IE8 30 | // where `console.log` doesn't have 'apply' 31 | window.console 32 | && console.log 33 | && Function.prototype.apply.call(console.log, console, arguments); 34 | } 35 | } 36 | 37 | /** 38 | * The currently active debug mode names. 39 | */ 40 | 41 | debug.names = []; 42 | debug.skips = []; 43 | 44 | /** 45 | * Enables a debug mode by name. This can include modes 46 | * separated by a colon and wildcards. 47 | * 48 | * @param {String} name 49 | * @api public 50 | */ 51 | 52 | debug.enable = function(name) { 53 | localStorage.debug = name; 54 | 55 | var split = (name || '').split(/[\s,]+/) 56 | , len = split.length; 57 | 58 | for (var i = 0; i < len; i++) { 59 | name = split[i].replace('*', '.*?'); 60 | if (name[0] === '-') { 61 | debug.skips.push(new RegExp('^' + name.substr(1) + '$')); 62 | } 63 | else { 64 | debug.names.push(new RegExp('^' + name + '$')); 65 | } 66 | } 67 | }; 68 | 69 | /** 70 | * Disable debug output. 71 | * 72 | * @api public 73 | */ 74 | 75 | debug.disable = function(){ 76 | debug.enable(''); 77 | }; 78 | 79 | /** 80 | * Humanize the given `ms`. 81 | * 82 | * @param {Number} m 83 | * @return {String} 84 | * @api private 85 | */ 86 | 87 | debug.humanize = function(ms) { 88 | var sec = 1000 89 | , min = 60 * 1000 90 | , hour = 60 * min; 91 | 92 | if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; 93 | if (ms >= min) return (ms / min).toFixed(1) + 'm'; 94 | if (ms >= sec) return (ms / sec | 0) + 's'; 95 | return ms + 'ms'; 96 | }; 97 | 98 | /** 99 | * Returns true if the given mode name is enabled, false otherwise. 100 | * 101 | * @param {String} name 102 | * @return {Boolean} 103 | * @api public 104 | */ 105 | 106 | debug.enabled = function(name) { 107 | for (var i = 0, len = debug.skips.length; i < len; i++) { 108 | if (debug.skips[i].test(name)) { 109 | return false; 110 | } 111 | } 112 | for (var i = 0, len = debug.names.length; i < len; i++) { 113 | if (debug.names[i].test(name)) { 114 | return true; 115 | } 116 | } 117 | return false; 118 | }; 119 | 120 | // persist 121 | 122 | if (window.localStorage) debug.enable(localStorage.debug); -------------------------------------------------------------------------------- /support/debug/example/app.js: -------------------------------------------------------------------------------- 1 | 2 | var debug = require('../')('http') 3 | , http = require('http') 4 | , name = 'My App'; 5 | 6 | // fake app 7 | 8 | debug('booting %s', name); 9 | 10 | http.createServer(function(req, res){ 11 | debug(req.method + ' ' + req.url); 12 | res.end('hello\n'); 13 | }).listen(3000, function(){ 14 | debug('listening'); 15 | }); 16 | 17 | // fake worker of some kind 18 | 19 | require('./worker'); -------------------------------------------------------------------------------- /support/debug/example/browser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | debug() 4 | 5 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /support/debug/example/wildcards.js: -------------------------------------------------------------------------------- 1 | 2 | var debug = { 3 | foo: require('../')('test:foo'), 4 | bar: require('../')('test:bar'), 5 | baz: require('../')('test:baz') 6 | }; 7 | 8 | debug.foo('foo') 9 | debug.bar('bar') 10 | debug.baz('baz') -------------------------------------------------------------------------------- /support/debug/example/worker.js: -------------------------------------------------------------------------------- 1 | 2 | // DEBUG=* node example/worker 3 | // DEBUG=worker:* node example/worker 4 | // DEBUG=worker:a node example/worker 5 | // DEBUG=worker:b node example/worker 6 | 7 | var a = require('../')('worker:a') 8 | , b = require('../')('worker:b'); 9 | 10 | function work() { 11 | a('doing lots of uninteresting work'); 12 | setTimeout(work, Math.random() * 1000); 13 | } 14 | 15 | work(); 16 | 17 | function workb() { 18 | b('doing some work'); 19 | setTimeout(workb, Math.random() * 2000); 20 | } 21 | 22 | workb(); -------------------------------------------------------------------------------- /support/debug/index.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = require('./lib/debug'); -------------------------------------------------------------------------------- /support/debug/lib/debug.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * debug 4 | * Copyright(c) 2012 TJ Holowaychuk 5 | * MIT Licensed 6 | */ 7 | 8 | /** 9 | * Module dependencies. 10 | */ 11 | 12 | var tty = require('tty'); 13 | 14 | /** 15 | * Expose `debug()` as the module. 16 | */ 17 | 18 | module.exports = debug; 19 | 20 | /** 21 | * Library version. 22 | */ 23 | 24 | exports.version = '0.6.0'; 25 | 26 | /** 27 | * Enabled debuggers. 28 | */ 29 | 30 | var names = [] 31 | , skips = []; 32 | 33 | (process.env.DEBUG || '') 34 | .split(/[\s,]+/) 35 | .forEach(function(name){ 36 | name = name.replace('*', '.*?'); 37 | if (name[0] === '-') { 38 | skips.push(new RegExp('^' + name.substr(1) + '$')); 39 | } else { 40 | names.push(new RegExp('^' + name + '$')); 41 | } 42 | }); 43 | 44 | /** 45 | * Colors. 46 | */ 47 | 48 | var colors = [6, 2, 3, 4, 5, 1]; 49 | 50 | /** 51 | * Previous debug() call. 52 | */ 53 | 54 | var prev = {}; 55 | 56 | /** 57 | * Previously assigned color. 58 | */ 59 | 60 | var prevColor = 0; 61 | 62 | /** 63 | * Is stdout a TTY? Colored output is disabled when `true`. 64 | */ 65 | 66 | var isatty = tty.isatty(2); 67 | 68 | /** 69 | * Select a color. 70 | * 71 | * @return {Number} 72 | * @api private 73 | */ 74 | 75 | function color() { 76 | return colors[prevColor++ % colors.length]; 77 | } 78 | 79 | /** 80 | * Humanize the given `ms`. 81 | * 82 | * @param {Number} m 83 | * @return {String} 84 | * @api private 85 | */ 86 | 87 | function humanize(ms) { 88 | var sec = 1000 89 | , min = 60 * 1000 90 | , hour = 60 * min; 91 | 92 | if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; 93 | if (ms >= min) return (ms / min).toFixed(1) + 'm'; 94 | if (ms >= sec) return (ms / sec | 0) + 's'; 95 | return ms + 'ms'; 96 | } 97 | 98 | /** 99 | * Create a debugger with the given `name`. 100 | * 101 | * @param {String} name 102 | * @return {Type} 103 | * @api public 104 | */ 105 | 106 | function debug(name) { 107 | function disabled(){} 108 | disabled.enabled = false; 109 | 110 | var match = skips.some(function(re){ 111 | return re.test(name); 112 | }); 113 | 114 | if (match) return disabled; 115 | 116 | match = names.some(function(re){ 117 | return re.test(name); 118 | }); 119 | 120 | if (!match) return disabled; 121 | var c = color(); 122 | 123 | function colored(fmt) { 124 | var curr = new Date; 125 | var ms = curr - (prev[name] || curr); 126 | prev[name] = curr; 127 | 128 | fmt = ' \033[9' + c + 'm' + name + ' ' 129 | + '\033[3' + c + 'm\033[90m' 130 | + fmt + '\033[3' + c + 'm' 131 | + ' +' + humanize(ms) + '\033[0m'; 132 | 133 | console.error.apply(this, arguments); 134 | } 135 | 136 | function plain(fmt) { 137 | fmt = new Date().toUTCString() 138 | + ' ' + name + ' ' + fmt; 139 | console.error.apply(this, arguments); 140 | } 141 | 142 | colored.enabled = plain.enabled = true; 143 | 144 | return isatty 145 | ? colored 146 | : plain; 147 | } 148 | -------------------------------------------------------------------------------- /support/debug/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "debug" 3 | , "version": "0.6.0" 4 | , "description": "small debugging utility" 5 | , "keywords": ["debug", "log", "debugger"] 6 | , "author": "TJ Holowaychuk " 7 | , "dependencies": {} 8 | , "devDependencies": { "mocha": "*" } 9 | , "main": "index" 10 | , "engines": { "node": "*" } 11 | } --------------------------------------------------------------------------------