From 8d4a241b1c4b44bc504ab278c64777a327b0ae74 Mon Sep 17 00:00:00 2001 From: Hugh Kennedy Date: Sat, 20 Jul 2013 17:06:21 +1000 Subject: [PATCH 01/27] Use transforms with --deps and --list flags. Allows transformed scripts to be parsed correctly for dependencies. Currently, using these options in combination with coffeeify or brfs (among others) will throw a syntax error. --- bin/cmd.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/cmd.js b/bin/cmd.js index 26a8ad167..59cb230d5 100755 --- a/bin/cmd.js +++ b/bin/cmd.js @@ -37,13 +37,15 @@ if (b.argv.pack) { if (b.argv.deps) { var stringify = JSONStream.stringify(); - var d = b.deps({ packageFilter: packageFilter }); + var t = [].concat(b.argv.t).concat(b.argv.transform); + var d = b.deps({ packageFilter: packageFilter, transform: t }); d.pipe(stringify).pipe(process.stdout); return; } if (b.argv.list) { - var d = b.deps({ packageFilter: packageFilter }); + var t = [].concat(b.argv.t).concat(b.argv.transform); + var d = b.deps({ packageFilter: packageFilter, transform: t }); d.pipe(through(function (dep) { this.queue(dep.id + '\n'); })).pipe(process.stdout); From 83c28001d94c7933d1d460066547100c302e23c7 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Thu, 25 Jul 2013 11:56:25 -0700 Subject: [PATCH 02/27] 2.25.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea94c7aa2..7c7ec23e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "browserify", - "version": "2.25.0", + "version": "2.25.1", "description": "browser-side require() the node way", "main": "index.js", "bin": { From d0f365747625ee11c1b84c05c41afb65160a96b6 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Fri, 2 Aug 2013 15:46:12 -0700 Subject: [PATCH 03/27] bump browser-pack for web workers --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c7ec23e4..acb8dfe80 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ ], "dependencies": { "module-deps": "~1.0.1", - "browser-pack": "~0.9.4", + "browser-pack": "~0.10.0", "deps-sort": "~0.1.1", "shell-quote": "~0.0.1", "through": "~2.3.4", From 901c66586f65eabd8d1e2d7527fdef8dde01f871 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Fri, 2 Aug 2013 15:46:23 -0700 Subject: [PATCH 04/27] 2.26.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index acb8dfe80..483646cbf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "browserify", - "version": "2.25.1", + "version": "2.26.0", "description": "browser-side require() the node way", "main": "index.js", "bin": { From c8a43404689ac5f33f5775490dce8321d447cd52 Mon Sep 17 00:00:00 2001 From: Justin Reidy Date: Thu, 15 Aug 2013 10:08:03 -0700 Subject: [PATCH 05/27] Allow arbitrary external ids Right now, ids used to reference modules in external bundles are required to correspond to actual files, but it'd be helpful if these ids could be arbitrary. This issue has been brought up in #387 and #472. A small change to how external modules are loaded, combined with using the mdeps filter option, allows for arbitrary external ids. This commit includes test coverage. --- index.js | 15 +++++++----- test/reverse_multi_bundle.js | 33 ++++++++++++++------------ test/reverse_multi_bundle/arbitrary.js | 4 ++++ test/reverse_multi_bundle/lazy.js | 5 ++++ 4 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 test/reverse_multi_bundle/arbitrary.js diff --git a/index.js b/index.js index 86a070b7a..7efecf2ec 100644 --- a/index.js +++ b/index.js @@ -85,11 +85,13 @@ Browserify.prototype.require = function (id, opts) { packageFilter: packageFilter }; browserResolve(id, params, function (err, file) { - if (err) return self.emit('error', err); - if (!file) return self.emit('error', new Error( - 'module ' + JSON.stringify(id) + ' not found in require()' - )); - + if ((err || !file) && !opts.external) { + if (err) return self.emit('error', err); + if (!file) return self.emit('error', new Error( + 'module ' + JSON.stringify(id) + ' not found in require()' + )); + } + if (opts.expose) { self.exports[file] = hash(file); @@ -100,7 +102,8 @@ Browserify.prototype.require = function (id, opts) { } if (opts.external) { - self._external[file] = true; + if (file) self._external[file] = true; + else self._external[id] = true; } else { self.files.push(file); diff --git a/test/reverse_multi_bundle.js b/test/reverse_multi_bundle.js index 09682e422..b1a2be0e2 100644 --- a/test/reverse_multi_bundle.js +++ b/test/reverse_multi_bundle.js @@ -10,34 +10,37 @@ var vm = require('vm'); var test = require('tap').test; test('reverse multi bundle', function (t) { - t.plan(4); + t.plan(5); // Main app bundle has the main app code and the shared libarary code var app = browserify([__dirname + '/reverse_multi_bundle/app.js']) .external(__dirname + '/reverse_multi_bundle/lazy.js') - .require(__dirname + '/reverse_multi_bundle/shared.js'); + .require(__dirname + '/reverse_multi_bundle/shared.js') + .require(__dirname + '/reverse_multi_bundle/arbitrary.js', {expose: 'not/real'}); // Lazily loaded bundle has only its own code even it uses code from the // shared library. var lazy = browserify() .require(__dirname + '/reverse_multi_bundle/lazy.js') - .external(__dirname + '/reverse_multi_bundle/shared.js'); + .external(__dirname + '/reverse_multi_bundle/shared.js') + .external('not/real'); app.bundle(function (err, appSrc) { if (err) throw err; - lazy.bundle(function(err, lazySrc) { - if (err) throw err; - - var src = appSrc + lazySrc; - var c = { - setTimeout: setTimeout, - t: t - }; - vm.runInNewContext(src, c); + lazy.bundle({ + filter: function (id) { + return id !== 'not/real'; + } + }, function(err, lazySrc) { + if (err) throw err; + + var src = appSrc + lazySrc; + var c = { + setTimeout: setTimeout, + t: t + }; + vm.runInNewContext(src, c); }); - }); - - }); diff --git a/test/reverse_multi_bundle/arbitrary.js b/test/reverse_multi_bundle/arbitrary.js new file mode 100644 index 000000000..8bce3202f --- /dev/null +++ b/test/reverse_multi_bundle/arbitrary.js @@ -0,0 +1,4 @@ +var i = 0; +module.exports = function() { + return ++i; +}; diff --git a/test/reverse_multi_bundle/lazy.js b/test/reverse_multi_bundle/lazy.js index 968673b35..012cdeb73 100644 --- a/test/reverse_multi_bundle/lazy.js +++ b/test/reverse_multi_bundle/lazy.js @@ -2,3 +2,8 @@ t.equal( require("./shared")(),2, "lazy.js can use the shared library" ); +t.equal( + require("not/real")(),1, + "lazy.js can use library code with arbitrary names" +); + From bd146cf8ab22d5d9801e2003cb15d70bb4447b03 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Thu, 15 Aug 2013 12:53:49 -0700 Subject: [PATCH 06/27] 2.27.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 483646cbf..ed33f179a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "browserify", - "version": "2.26.0", + "version": "2.27.0", "description": "browser-side require() the node way", "main": "index.js", "bin": { From edc3c3f6c15b737d2800e9570b15b0ff66b2c65f Mon Sep 17 00:00:00 2001 From: James Halliday Date: Thu, 15 Aug 2013 14:31:11 -0700 Subject: [PATCH 07/27] -x works again for non-core module names --- bin/args.js | 5 ++++- index.js | 17 +++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/bin/args.js b/bin/args.js index 569da8dd5..1844ac469 100644 --- a/bin/args.js +++ b/bin/args.js @@ -46,7 +46,10 @@ module.exports = function (args) { // resolve any external files and add them to the bundle as externals [].concat(argv.x).concat(argv.external).filter(Boolean) - .forEach(function (x) { b.external(path.resolve(process.cwd(), x)) }) + .forEach(function (x) { + if (/^[\/.]/.test(x)) b.external(path.resolve(process.cwd(), x)) + else b.external(x) + }) ; [].concat(argv.t).concat(argv.transform).filter(Boolean) diff --git a/index.js b/index.js index 7efecf2ec..3eb08bd55 100644 --- a/index.js +++ b/index.js @@ -91,7 +91,7 @@ Browserify.prototype.require = function (id, opts) { 'module ' + JSON.stringify(id) + ' not found in require()' )); } - + if (opts.expose) { self.exports[file] = hash(file); @@ -100,7 +100,7 @@ Browserify.prototype.require = function (id, opts) { self._mapped[opts.expose] = file; } } - + if (opts.external) { if (file) self._external[file] = true; else self._external[id] = true; @@ -389,10 +389,15 @@ Browserify.prototype._resolve = function (id, parent, cb) { return browserResolve(id, parent, function(err, file, pkg) { if (err) return cb(err); - if (!file) return cb(new Error('module ' - + JSON.stringify(id) + ' not found from ' - + JSON.stringify(parent.filename) - )); + if (!file && (self._external[id] || self._external[file])) { + return cb(null, emptyModulePath); + } + else if (!file) { + return cb(new Error('module ' + + JSON.stringify(id) + ' not found from ' + + JSON.stringify(parent.filename) + )); + } if (self._ignore[file]) return cb(null, emptyModulePath); if (self._external[file]) return result(file, pkg, true); From 860c95f48d2bc2e7fcb991b3fa21cd2ec595a724 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Thu, 15 Aug 2013 14:41:56 -0700 Subject: [PATCH 08/27] fix for external core module names --- index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.js b/index.js index 3eb08bd55..6f1d3d966 100644 --- a/index.js +++ b/index.js @@ -387,6 +387,8 @@ Browserify.prototype._resolve = function (id, parent, cb) { parent.modules = browserBuiltins; + if (self._external[id]) return cb(null, emptyModulePath); + return browserResolve(id, parent, function(err, file, pkg) { if (err) return cb(err); if (!file && (self._external[id] || self._external[file])) { From b26e13d1f9d7822be5214316782ac4eddd0598aa Mon Sep 17 00:00:00 2001 From: James Halliday Date: Thu, 15 Aug 2013 15:14:49 -0700 Subject: [PATCH 09/27] filter deps for externals --- index.js | 9 ++++++++- package.json | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 6f1d3d966..e1dca7987 100644 --- a/index.js +++ b/index.js @@ -18,6 +18,8 @@ var inherits = require('inherits'); var EventEmitter = require('events').EventEmitter; var fs = require('fs'); +var emptyModulePath = path.join(__dirname, '_empty.js'); + module.exports = function (opts) { if (opts === undefined) opts = {}; if (typeof opts === 'string') opts = { entries: [ opts ] }; @@ -238,6 +240,12 @@ Browserify.prototype.deps = function (opts) { if (row.id === emptyModulePath) { row.source = ''; } + row.deps = Object.keys(row.deps).reduce(function (acc, key) { + if (!self._external[key] && !self._external[row.id]) { + acc[key] = row.deps[key]; + } + return acc; + }, {}); if (self._expose[row.id]) { this.queue({ @@ -354,7 +362,6 @@ var packageFilter = function (info) { return info; }; -var emptyModulePath = require.resolve('./_empty'); Browserify.prototype._resolve = function (id, parent, cb) { if (this._ignore[id]) return cb(null, emptyModulePath); var self = this; diff --git a/package.json b/package.json index ed33f179a..3c7b66c1e 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "javascript" ], "dependencies": { - "module-deps": "~1.0.1", + "module-deps": "~1.0.2", "browser-pack": "~0.10.0", "deps-sort": "~0.1.1", "shell-quote": "~0.0.1", From d89888bad0491a3b5fb2231ba142cca71f37154c Mon Sep 17 00:00:00 2001 From: James Halliday Date: Thu, 15 Aug 2013 15:20:32 -0700 Subject: [PATCH 10/27] external test passes --- test/external.js | 20 ++++++++++++++++++++ test/external/main.js | 2 ++ test/external/x.js | 3 +++ 3 files changed, 25 insertions(+) create mode 100644 test/external.js create mode 100644 test/external/main.js create mode 100644 test/external/x.js diff --git a/test/external.js b/test/external.js new file mode 100644 index 000000000..a107a4cfc --- /dev/null +++ b/test/external.js @@ -0,0 +1,20 @@ +var browserify = require('../'); +var vm = require('vm'); +var test = require('tap').test; + +test('external', function (t) { + t.plan(2); + + var b = browserify(__dirname + '/external/main.js'); + b.external('freelist'); + b.bundle(function (err, src) { + if (err) return t.fail(err); + vm.runInNewContext( + 'function require (x) {' + + 'if (x==="freelist") return function (n) { return n + 1000 }' + + '}' + + src, + { t: t } + ); + }); +}); diff --git a/test/external/main.js b/test/external/main.js new file mode 100644 index 000000000..82ceeda83 --- /dev/null +++ b/test/external/main.js @@ -0,0 +1,2 @@ +t.equal(require('freelist')(5), 1005); +t.equal(require('./x.js')(6), 1016); diff --git a/test/external/x.js b/test/external/x.js new file mode 100644 index 000000000..a587ef44a --- /dev/null +++ b/test/external/x.js @@ -0,0 +1,3 @@ +var fl = require('freelist'); + +module.exports = function (n) { return fl(n) + 10 }; From cc2fb080cc80633e7f87a3df1ede7e0e8c5ac764 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Thu, 15 Aug 2013 15:22:55 -0700 Subject: [PATCH 11/27] 2.27.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3c7b66c1e..1c93a9899 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "browserify", - "version": "2.27.0", + "version": "2.27.1", "description": "browser-side require() the node way", "main": "index.js", "bin": { From b24fbc3d8d9ba775d9b70a31d0b5d21be084a9e7 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sun, 18 Aug 2013 15:47:01 -0700 Subject: [PATCH 12/27] make `browserify -r events --standalone EventEmitter` work --- bin/args.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bin/args.js b/bin/args.js index 1844ac469..0d5b78e1d 100644 --- a/bin/args.js +++ b/bin/args.js @@ -27,6 +27,12 @@ module.exports = function (args) { return path.resolve(process.cwd(), entry); }); + if (argv.s && entries.length === 0 + && [].concat(argv.r, argv.require).filter(Boolean).length === 1) { + entries.push([].concat(argv.r, argv.require).filter(Boolean)[0]); + argv.r = argv.require = []; + } + var b = browserify({ noParse: [].concat(argv.noparse).filter(Boolean), entries: entries From a0f226130621670034f3b72b740b9c5253146db9 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sun, 18 Aug 2013 15:47:22 -0700 Subject: [PATCH 13/27] 2.28.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c93a9899..9e558f31a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "browserify", - "version": "2.27.1", + "version": "2.28.0", "description": "browser-side require() the node way", "main": "index.js", "bin": { From 9b6f2cbb71cad5e25371b728ccf52ff556d517c1 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 20:24:19 -0700 Subject: [PATCH 14/27] hash test checks correct behavior for duplicate files --- test/hash.js | 13 +++++++++++++ test/hash/foo/other.js | 1 + test/hash/foo/two.js | 2 ++ test/hash/main.js | 2 ++ test/hash/one.js | 2 ++ test/hash/other.js | 1 + 6 files changed, 21 insertions(+) create mode 100644 test/hash.js create mode 100644 test/hash/foo/other.js create mode 100644 test/hash/foo/two.js create mode 100644 test/hash/main.js create mode 100644 test/hash/one.js create mode 100644 test/hash/other.js diff --git a/test/hash.js b/test/hash.js new file mode 100644 index 000000000..0f8e12dbe --- /dev/null +++ b/test/hash.js @@ -0,0 +1,13 @@ +var browserify = require('../'); +var vm = require('vm'); +var test = require('tap').test; + +test('hash', function (t) { + t.plan(2); + + var b = browserify(__dirname + '/hash/main.js'); + b.bundle(function (err, src) { + var c = { t: t }; + vm.runInNewContext(src, c); + }); +}); diff --git a/test/hash/foo/other.js b/test/hash/foo/other.js new file mode 100644 index 000000000..f4e8d9d29 --- /dev/null +++ b/test/hash/foo/other.js @@ -0,0 +1 @@ +module.exports = 5; diff --git a/test/hash/foo/two.js b/test/hash/foo/two.js new file mode 100644 index 000000000..86c05b925 --- /dev/null +++ b/test/hash/foo/two.js @@ -0,0 +1,2 @@ +// FILE CONTENTS +module.exports = 111 * require('./other.js'); diff --git a/test/hash/main.js b/test/hash/main.js new file mode 100644 index 000000000..b37dd8831 --- /dev/null +++ b/test/hash/main.js @@ -0,0 +1,2 @@ +t.equal(require('./foo/two.js'), 555); +t.equal(require('./one.js'), 333); diff --git a/test/hash/one.js b/test/hash/one.js new file mode 100644 index 000000000..86c05b925 --- /dev/null +++ b/test/hash/one.js @@ -0,0 +1,2 @@ +// FILE CONTENTS +module.exports = 111 * require('./other.js'); diff --git a/test/hash/other.js b/test/hash/other.js new file mode 100644 index 000000000..690aad34a --- /dev/null +++ b/test/hash/other.js @@ -0,0 +1 @@ +module.exports = 3; From a9b33cb2df8eb98fb9b31be799ee9c5f70a31477 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 20:26:45 -0700 Subject: [PATCH 15/27] failing check for only 1 duplicate file included --- test/hash.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/hash.js b/test/hash.js index 0f8e12dbe..c1d513b87 100644 --- a/test/hash.js +++ b/test/hash.js @@ -3,11 +3,12 @@ var vm = require('vm'); var test = require('tap').test; test('hash', function (t) { - t.plan(2); + t.plan(3); var b = browserify(__dirname + '/hash/main.js'); b.bundle(function (err, src) { var c = { t: t }; + t.equal(src.match(RegExp('// FILE CONTENTS', 'g')).length, 1); vm.runInNewContext(src, c); }); }); From 356bf6ab45c83c65c278f177d69278102a36d026 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 21:14:58 -0700 Subject: [PATCH 16/27] files with the same hash only included once --- index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/index.js b/index.js index e1dca7987..56f907386 100644 --- a/index.js +++ b/index.js @@ -278,6 +278,7 @@ Browserify.prototype.pack = function (debug, standalone) { var packer = browserPack({ raw: true }); var mainModule; + var hashes = {}; var input = through(function (row_) { var row = copy(row_); @@ -287,6 +288,16 @@ Browserify.prototype.pack = function (debug, standalone) { row.sourceFile = row.id; } + var srcHash = hash(row.source); + var dup = hashes[srcHash]; + if (dup) { + row.source = 'arguments[4][' + + JSON.stringify(getId(dup)) + + '][0].apply(exports,arguments)' + ; + } + else hashes[srcHash] = row; + if (/^#!/.test(row.source)) row.source = '//' + row.source; var err = checkSyntax(row.source, row.id); if (err) return this.emit('error', err); From ee84403e2f71e5e9d2acd39cefa8a12a9fb19f64 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 21:38:19 -0700 Subject: [PATCH 17/27] failing test for hash instances --- test/hash_instance.js | 14 ++++++++++++++ test/hash_instance/foo/two.js | 3 +++ test/hash_instance/main.js | 11 +++++++++++ test/hash_instance/one.js | 3 +++ 4 files changed, 31 insertions(+) create mode 100644 test/hash_instance.js create mode 100644 test/hash_instance/foo/two.js create mode 100644 test/hash_instance/main.js create mode 100644 test/hash_instance/one.js diff --git a/test/hash_instance.js b/test/hash_instance.js new file mode 100644 index 000000000..a34c82cde --- /dev/null +++ b/test/hash_instance.js @@ -0,0 +1,14 @@ +var browserify = require('../'); +var vm = require('vm'); +var test = require('tap').test; + +test('hash instances', function (t) { + t.plan(6); + + var b = browserify(__dirname + '/hash_instance/main.js'); + b.bundle(function (err, src) { + var c = { t: t }; + t.equal(src.match(RegExp('// abcdefg', 'g')).length, 1); + vm.runInNewContext(src, c); + }); +}); diff --git a/test/hash_instance/foo/two.js b/test/hash_instance/foo/two.js new file mode 100644 index 000000000..9fee06365 --- /dev/null +++ b/test/hash_instance/foo/two.js @@ -0,0 +1,3 @@ +// abcdefg +module.exports = Foo; +function Foo () {} diff --git a/test/hash_instance/main.js b/test/hash_instance/main.js new file mode 100644 index 000000000..a77abb25b --- /dev/null +++ b/test/hash_instance/main.js @@ -0,0 +1,11 @@ +var Foo1 = require('./one.js'); +var Foo2 = require('./foo/two.js'); + +var f1 = new Foo1; +var f2 = new Foo2; + +t.equal(Foo1, Foo2); +t.ok(f1 instanceof Foo1); +t.ok(f1 instanceof Foo2); +t.ok(f2 instanceof Foo1); +t.ok(f2 instanceof Foo2); diff --git a/test/hash_instance/one.js b/test/hash_instance/one.js new file mode 100644 index 000000000..9fee06365 --- /dev/null +++ b/test/hash_instance/one.js @@ -0,0 +1,3 @@ +// abcdefg +module.exports = Foo; +function Foo () {} From ef1589e975f629f3b06a231eba2e822734934d73 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 22:10:01 -0700 Subject: [PATCH 18/27] passing the hash instance test with a naive sameDeps() checker --- index.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 56f907386..505ae4818 100644 --- a/index.js +++ b/index.js @@ -290,7 +290,13 @@ Browserify.prototype.pack = function (debug, standalone) { var srcHash = hash(row.source); var dup = hashes[srcHash]; - if (dup) { + if (dup && sameDeps(dup.deps, row.deps, hashes)) { + row.source = 'module.exports=require(' + + JSON.stringify(getId(dup)) + + ')' + ; + } + else if (dup) { row.source = 'arguments[4][' + JSON.stringify(getId(dup)) + '][0].apply(exports,arguments)' @@ -461,3 +467,14 @@ function copy (obj) { return acc; }, {}); } + +function sameDeps (a, b, hashes) { + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) return false; + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (a[key] !== b[key]) return false; + } + return true; +} From d62b317f5d51a12ae89215da8816786252355412 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 22:12:15 -0700 Subject: [PATCH 19/27] update the reverse multi bundle test for hash matching to not depend on side effects in files with the same hash --- test/reverse_multi_bundle/arbitrary.js | 2 ++ test/reverse_multi_bundle/shared.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/reverse_multi_bundle/arbitrary.js b/test/reverse_multi_bundle/arbitrary.js index 8bce3202f..ba7d87215 100644 --- a/test/reverse_multi_bundle/arbitrary.js +++ b/test/reverse_multi_bundle/arbitrary.js @@ -2,3 +2,5 @@ var i = 0; module.exports = function() { return ++i; }; + +// 175e62 diff --git a/test/reverse_multi_bundle/shared.js b/test/reverse_multi_bundle/shared.js index 8bce3202f..6bb03fbba 100644 --- a/test/reverse_multi_bundle/shared.js +++ b/test/reverse_multi_bundle/shared.js @@ -2,3 +2,5 @@ var i = 0; module.exports = function() { return ++i; }; + +// 77aa70 From 92b309225a5a895856dfd01b508a027190e028ff Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 23:07:27 -0700 Subject: [PATCH 20/27] passing hash instance context test dealing with single-level nested dependencies --- test/hash_instance_context.js | 20 ++++++++++++++++++++ test/hash_instance_context/main.js | 11 +++++++++++ test/hash_instance_context/one/dir/f.js | 3 +++ test/hash_instance_context/one/dir/g.js | 2 ++ test/hash_instance_context/one/f.js | 3 +++ test/hash_instance_context/one/g.js | 2 ++ test/hash_instance_context/two/dir/f.js | 3 +++ test/hash_instance_context/two/dir/g.js | 2 ++ test/hash_instance_context/two/dir/h.js | 2 ++ test/hash_instance_context/two/f.js | 3 +++ test/hash_instance_context/two/g.js | 2 ++ test/hash_instance_context/two/h.js | 2 ++ 12 files changed, 55 insertions(+) create mode 100644 test/hash_instance_context.js create mode 100644 test/hash_instance_context/main.js create mode 100644 test/hash_instance_context/one/dir/f.js create mode 100644 test/hash_instance_context/one/dir/g.js create mode 100644 test/hash_instance_context/one/f.js create mode 100644 test/hash_instance_context/one/g.js create mode 100644 test/hash_instance_context/two/dir/f.js create mode 100644 test/hash_instance_context/two/dir/g.js create mode 100644 test/hash_instance_context/two/dir/h.js create mode 100644 test/hash_instance_context/two/f.js create mode 100644 test/hash_instance_context/two/g.js create mode 100644 test/hash_instance_context/two/h.js diff --git a/test/hash_instance_context.js b/test/hash_instance_context.js new file mode 100644 index 000000000..59f447c8f --- /dev/null +++ b/test/hash_instance_context.js @@ -0,0 +1,20 @@ +var browserify = require('../'); +var vm = require('vm'); +var test = require('tap').test; + +test('hash instances with hashed contexts', function (t) { + t.plan(11); + + var b = browserify(__dirname + '/hash_instance_context/main.js'); + b.bundle(function (err, src) { + var c = { t: t }; + t.equal(src.match(RegExp('// FILE F ONE', 'g')).length, 1); + t.equal(src.match(RegExp('// FILE G ONE', 'g')).length, 2); + + t.equal(src.match(RegExp('// FILE F TWO', 'g')).length, 1); + t.equal(src.match(RegExp('// FILE G TWO', 'g')).length, 1); + t.equal(src.match(RegExp('// FILE H TWO', 'g')).length, 2); + + vm.runInNewContext(src, c); + }); +}); diff --git a/test/hash_instance_context/main.js b/test/hash_instance_context/main.js new file mode 100644 index 000000000..d95e2c4e6 --- /dev/null +++ b/test/hash_instance_context/main.js @@ -0,0 +1,11 @@ +var A = require('./one/f.js'); +var B = require('./one/dir/f.js'); +t.notEqual(A, B); +t.equal(A(), 555); +t.equal(B(), 333); + +var C = require('./two/f.js'); +var D = require('./two/dir/f.js'); +t.notEqual(C, D); +t.equal(C(), 555); +t.equal(D(), 333); diff --git a/test/hash_instance_context/one/dir/f.js b/test/hash_instance_context/one/dir/f.js new file mode 100644 index 000000000..a315c1e7d --- /dev/null +++ b/test/hash_instance_context/one/dir/f.js @@ -0,0 +1,3 @@ +// FILE F ONE +var G = require('./g.js'); +module.exports = function () { return 111 * G }; diff --git a/test/hash_instance_context/one/dir/g.js b/test/hash_instance_context/one/dir/g.js new file mode 100644 index 000000000..9cab61b8d --- /dev/null +++ b/test/hash_instance_context/one/dir/g.js @@ -0,0 +1,2 @@ +// FILE G ONE +module.exports = 3 diff --git a/test/hash_instance_context/one/f.js b/test/hash_instance_context/one/f.js new file mode 100644 index 000000000..a315c1e7d --- /dev/null +++ b/test/hash_instance_context/one/f.js @@ -0,0 +1,3 @@ +// FILE F ONE +var G = require('./g.js'); +module.exports = function () { return 111 * G }; diff --git a/test/hash_instance_context/one/g.js b/test/hash_instance_context/one/g.js new file mode 100644 index 000000000..837303206 --- /dev/null +++ b/test/hash_instance_context/one/g.js @@ -0,0 +1,2 @@ +// FILE G ONE +module.exports = 5 diff --git a/test/hash_instance_context/two/dir/f.js b/test/hash_instance_context/two/dir/f.js new file mode 100644 index 000000000..1178f93fb --- /dev/null +++ b/test/hash_instance_context/two/dir/f.js @@ -0,0 +1,3 @@ +// FILE F TWO +var G = require('./g.js'); +module.exports = function () { return 111 * G }; diff --git a/test/hash_instance_context/two/dir/g.js b/test/hash_instance_context/two/dir/g.js new file mode 100644 index 000000000..b940ee76f --- /dev/null +++ b/test/hash_instance_context/two/dir/g.js @@ -0,0 +1,2 @@ +// FILE G TWO +module.exports = require('./h.js') + 1; diff --git a/test/hash_instance_context/two/dir/h.js b/test/hash_instance_context/two/dir/h.js new file mode 100644 index 000000000..74a8a7a47 --- /dev/null +++ b/test/hash_instance_context/two/dir/h.js @@ -0,0 +1,2 @@ +// FILE H TWO +module.exports = 2 diff --git a/test/hash_instance_context/two/f.js b/test/hash_instance_context/two/f.js new file mode 100644 index 000000000..1178f93fb --- /dev/null +++ b/test/hash_instance_context/two/f.js @@ -0,0 +1,3 @@ +// FILE F TWO +var G = require('./g.js'); +module.exports = function () { return 111 * G }; diff --git a/test/hash_instance_context/two/g.js b/test/hash_instance_context/two/g.js new file mode 100644 index 000000000..b940ee76f --- /dev/null +++ b/test/hash_instance_context/two/g.js @@ -0,0 +1,2 @@ +// FILE G TWO +module.exports = require('./h.js') + 1; diff --git a/test/hash_instance_context/two/h.js b/test/hash_instance_context/two/h.js new file mode 100644 index 000000000..42684f036 --- /dev/null +++ b/test/hash_instance_context/two/h.js @@ -0,0 +1,2 @@ +// FILE H TWO +module.exports = 4 From 2ece4865bbee431059fa36a2b4aaafd7b358e733 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 24 Aug 2013 23:10:25 -0700 Subject: [PATCH 21/27] a failing test for nested hash instance contexts --- test/hash_instance_context.js | 6 +++++- test/hash_instance_context/main.js | 6 ++++++ test/hash_instance_context/three/dir/f.js | 3 +++ test/hash_instance_context/three/dir/g.js | 2 ++ test/hash_instance_context/three/dir/h.js | 2 ++ test/hash_instance_context/three/f.js | 3 +++ test/hash_instance_context/three/g.js | 2 ++ test/hash_instance_context/three/h.js | 2 ++ 8 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/hash_instance_context/three/dir/f.js create mode 100644 test/hash_instance_context/three/dir/g.js create mode 100644 test/hash_instance_context/three/dir/h.js create mode 100644 test/hash_instance_context/three/f.js create mode 100644 test/hash_instance_context/three/g.js create mode 100644 test/hash_instance_context/three/h.js diff --git a/test/hash_instance_context.js b/test/hash_instance_context.js index 59f447c8f..694d8602c 100644 --- a/test/hash_instance_context.js +++ b/test/hash_instance_context.js @@ -3,7 +3,7 @@ var vm = require('vm'); var test = require('tap').test; test('hash instances with hashed contexts', function (t) { - t.plan(11); + t.plan(17); var b = browserify(__dirname + '/hash_instance_context/main.js'); b.bundle(function (err, src) { @@ -15,6 +15,10 @@ test('hash instances with hashed contexts', function (t) { t.equal(src.match(RegExp('// FILE G TWO', 'g')).length, 1); t.equal(src.match(RegExp('// FILE H TWO', 'g')).length, 2); + t.equal(src.match(RegExp('// FILE F THREE', 'g')).length, 1); + t.equal(src.match(RegExp('// FILE G THREE', 'g')).length, 1); + t.equal(src.match(RegExp('// FILE H THREE', 'g')).length, 1); + vm.runInNewContext(src, c); }); }); diff --git a/test/hash_instance_context/main.js b/test/hash_instance_context/main.js index d95e2c4e6..3c4d3d6f4 100644 --- a/test/hash_instance_context/main.js +++ b/test/hash_instance_context/main.js @@ -9,3 +9,9 @@ var D = require('./two/dir/f.js'); t.notEqual(C, D); t.equal(C(), 555); t.equal(D(), 333); + +var E = require('./three/f.js'); +var F = require('./three/dir/f.js'); +t.equal(E, F); +t.equal(E(), 555); +t.equal(F(), 555); diff --git a/test/hash_instance_context/three/dir/f.js b/test/hash_instance_context/three/dir/f.js new file mode 100644 index 000000000..51b1e7327 --- /dev/null +++ b/test/hash_instance_context/three/dir/f.js @@ -0,0 +1,3 @@ +// FILE F THREE +var G = require('./g.js'); +module.exports = function () { return 111 * G }; diff --git a/test/hash_instance_context/three/dir/g.js b/test/hash_instance_context/three/dir/g.js new file mode 100644 index 000000000..654f021c3 --- /dev/null +++ b/test/hash_instance_context/three/dir/g.js @@ -0,0 +1,2 @@ +// FILE G THREE +module.exports = require('./h.js') + 1; diff --git a/test/hash_instance_context/three/dir/h.js b/test/hash_instance_context/three/dir/h.js new file mode 100644 index 000000000..afcc80fd3 --- /dev/null +++ b/test/hash_instance_context/three/dir/h.js @@ -0,0 +1,2 @@ +// FILE H THREE +module.exports = 4 diff --git a/test/hash_instance_context/three/f.js b/test/hash_instance_context/three/f.js new file mode 100644 index 000000000..51b1e7327 --- /dev/null +++ b/test/hash_instance_context/three/f.js @@ -0,0 +1,3 @@ +// FILE F THREE +var G = require('./g.js'); +module.exports = function () { return 111 * G }; diff --git a/test/hash_instance_context/three/g.js b/test/hash_instance_context/three/g.js new file mode 100644 index 000000000..654f021c3 --- /dev/null +++ b/test/hash_instance_context/three/g.js @@ -0,0 +1,2 @@ +// FILE G THREE +module.exports = require('./h.js') + 1; diff --git a/test/hash_instance_context/three/h.js b/test/hash_instance_context/three/h.js new file mode 100644 index 000000000..afcc80fd3 --- /dev/null +++ b/test/hash_instance_context/three/h.js @@ -0,0 +1,2 @@ +// FILE H THREE +module.exports = 4 From 63928d2c69ed9cb91d320128bfcd5f3cd5ab9f9d Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sun, 25 Aug 2013 00:40:05 -0700 Subject: [PATCH 22/27] nested hash instance contexts test passes with a more sophisticated recursive hash-aware dependency checker --- index.js | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index 505ae4818..756e6132b 100644 --- a/index.js +++ b/index.js @@ -278,7 +278,7 @@ Browserify.prototype.pack = function (debug, standalone) { var packer = browserPack({ raw: true }); var mainModule; - var hashes = {}; + var hashes = {}, depList = {}, depHash = {}; var input = through(function (row_) { var row = copy(row_); @@ -288,21 +288,20 @@ Browserify.prototype.pack = function (debug, standalone) { row.sourceFile = row.id; } - var srcHash = hash(row.source); - var dup = hashes[srcHash]; - if (dup && sameDeps(dup.deps, row.deps, hashes)) { + var dup = hashes[row.hash]; + if (dup && sameDeps(depList[dup._id], row.deps)) { row.source = 'module.exports=require(' - + JSON.stringify(getId(dup)) + + JSON.stringify(dup.id) + ')' ; } else if (dup) { row.source = 'arguments[4][' - + JSON.stringify(getId(dup)) + + JSON.stringify(dup.id) + '][0].apply(exports,arguments)' ; } - else hashes[srcHash] = row; + else hashes[row.hash] = { _id: row.id, id: getId(row) }; if (/^#!/.test(row.source)) row.source = '//' + row.source; var err = checkSyntax(row.source, row.id); @@ -344,7 +343,7 @@ Browserify.prototype.pack = function (debug, standalone) { var output = through(write, end); var sort = depSorter({ index: true }); - return pipeline(sort, input, packer, output); + return pipeline(through(hasher), sort, input, packer, output); function write (buf) { if (first) writePrelude.call(this); @@ -369,6 +368,29 @@ Browserify.prototype.pack = function (debug, standalone) { if (!hasExports) return this.queue(';'); this.queue('require='); } + + function hasher (row) { + row.hash = hash(row.source); + depList[row.id] = row.deps; + depHash[row.id] = row.hash; + this.queue(row); + } + + function sameDeps (a, b) { + var keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) return false; + + for (var i = 0; i < keys.length; i++) { + var k = keys[i], ka = a[k], kb = b[k]; + var ha = depHash[ka]; + var hb = depHash[kb]; + var da = depList[ka]; + var db = depList[kb]; + + if (ha !== hb || !sameDeps(da, db)) return false; + } + return true; + } }; var packageFilter = function (info) { @@ -467,14 +489,3 @@ function copy (obj) { return acc; }, {}); } - -function sameDeps (a, b, hashes) { - var keys = Object.keys(a); - if (keys.length !== Object.keys(b).length) return false; - - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - if (a[key] !== b[key]) return false; - } - return true; -} From 7d101ece30a347604778d11f9c31dbf9c39bb7b6 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sun, 25 Aug 2013 00:42:03 -0700 Subject: [PATCH 23/27] use stream-combiner directly instead of event-stream --- index.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 756e6132b..84f838253 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,6 @@ var crypto = require('crypto'); var through = require('through'); -var pipeline = require('event-stream').pipeline; +var pipeline = require('stream-combiner'); var concatStream = require('concat-stream'); var checkSyntax = require('syntax-error'); var parents = require('parents'); diff --git a/package.json b/package.json index 9e558f31a..ce3015e6a 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "shell-quote": "~0.0.1", "through": "~2.3.4", "duplexer": "~0.1.1", - "event-stream": "~3.0.15", + "stream-combiner": "~0.0.2", "concat-stream": "~1.0.0", "insert-module-globals": "~1.2.0", "syntax-error": "~0.0.0", From da4c2d643b281d6b6af0c49d37541a4eaed77926 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sun, 25 Aug 2013 00:43:07 -0700 Subject: [PATCH 24/27] 2.29.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce3015e6a..4bf320260 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "browserify", - "version": "2.28.0", + "version": "2.29.0", "description": "browser-side require() the node way", "main": "index.js", "bin": { From dc7c78e8ba09e9055b22fcbb3b7f01cd0c6af870 Mon Sep 17 00:00:00 2001 From: Noah Medling Date: Tue, 3 Sep 2013 16:39:13 -0500 Subject: [PATCH 25/27] Failing tests for sourcemaps on standalone builds. --- test/standalone_sourcemap.js | 74 ++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 test/standalone_sourcemap.js diff --git a/test/standalone_sourcemap.js b/test/standalone_sourcemap.js new file mode 100644 index 000000000..e60af00b3 --- /dev/null +++ b/test/standalone_sourcemap.js @@ -0,0 +1,74 @@ +var browserify = require('../'); +var vm = require('vm'); +var test = require('tap').test; + +test('standalone in debug mode', function (t) { + t.plan(5); + + var b = browserify(__dirname + '/standalone/main.js'); + b.bundle({standalone: 'stand-test', debug: true}, function (err, src) { + t.test('window global', function (t) { + t.plan(2); + var c = { + window: {}, + done : done(t) + }; + vm.runInNewContext(src + 'window.standTest(done)', c); + }); + t.test('CommonJS', function (t) { + t.plan(2); + var exp = {}; + var c = { + module: { exports: exp }, + exports: exp, + done : done(t) + }; + vm.runInNewContext(src + 'module.exports(done)', c); + }); + t.test('RequireJS', function (t) { + t.plan(2); + var c = { + define: function (fn) { + fn()(done(t)); + } + }; + c.define.amd = true; + vm.runInNewContext(src, c); + }); + t.test('MontageRequire', function (t) { + t.plan(3); + var c = { + bootstrap: function (name, fn) { + t.equal(name, 'stand-test'); + fn()(done(t)); + } + }; + vm.runInNewContext(src, c); + }); + t.test('SES (Secure Ecma Script)', function (t) { + t.plan(3); + var cOK = { + ses: { + ok: function () { return true; } + }, + done: done(t) + }; + var cNotOK = { + ses: { + ok: function () { return false; } + } + }; + t.equal(typeof vm.runInNewContext(src + 'ses.makeStandTest', cNotOK), 'undefined'); + vm.runInNewContext(src + 'ses.makeStandTest()(done)', cOK); + }); + }); +}); + +function done(t) { + return function (one, two) { + t.equal(one, 1); + t.equal(two, 2); + t.end(); + }; +} + From fc0f176314911b5b43307f0c1a3b542a6ae93249 Mon Sep 17 00:00:00 2001 From: Noah Medling Date: Tue, 3 Sep 2013 16:40:23 -0500 Subject: [PATCH 26/27] Standalone sourcemaps tests pass. --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 84f838253..937d9ed29 100644 --- a/index.js +++ b/index.js @@ -354,7 +354,7 @@ Browserify.prototype.pack = function (debug, standalone) { function end () { if (first) writePrelude.call(this); if (standalone) { - this.queue('(' + mainModule + ')' + umd.postlude(standalone)); + this.queue('\n(' + mainModule + ')' + umd.postlude(standalone)); } this.queue('\n;'); this.queue(null); From 1e5e0e909726b45654cbe9be8d932f164d368b92 Mon Sep 17 00:00:00 2001 From: James Halliday Date: Tue, 3 Sep 2013 15:57:28 -0700 Subject: [PATCH 27/27] 2.29.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4bf320260..1732cf104 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "browserify", - "version": "2.29.0", + "version": "2.29.1", "description": "browser-side require() the node way", "main": "index.js", "bin": {