From 9aec5cf88ccb0816a774fa5dee9ec685473c97de Mon Sep 17 00:00:00 2001 From: Robert Hurst Date: Wed, 20 Feb 2019 17:29:49 -0800 Subject: [PATCH 1/3] prevent circular deps from causing a stack overflow in hmr --- packages/core/parcel-bundler/src/builtins/hmr-runtime.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/core/parcel-bundler/src/builtins/hmr-runtime.js b/packages/core/parcel-bundler/src/builtins/hmr-runtime.js index 74efb86d4d6..6df54bcd895 100644 --- a/packages/core/parcel-bundler/src/builtins/hmr-runtime.js +++ b/packages/core/parcel-bundler/src/builtins/hmr-runtime.js @@ -20,6 +20,7 @@ function Module(moduleName) { } module.bundle.Module = Module; +var updatedAssets; var parent = module.bundle.parent; if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') { @@ -27,6 +28,8 @@ if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') { var protocol = location.protocol === 'https:' ? 'wss' : 'ws'; var ws = new WebSocket(protocol + '://' + hostname + ':' + process.env.HMR_PORT + '/'); ws.onmessage = function(event) { + updatedAssets = new Set(); + var data = JSON.parse(event.data); if (data.type === 'update') { @@ -147,6 +150,11 @@ function hmrAccept(bundle, id) { return hmrAccept(bundle.parent, id); } + if (updatedAssets.has(id)) { + return; + } + updatedAssets.add(id); + var cached = bundle.cache[id]; bundle.hotData = {}; if (cached) { From 62b5c8dc1f18b440eace6d774f23cfe230bb3927 Mon Sep 17 00:00:00 2001 From: Robert Hurst Date: Fri, 22 Feb 2019 09:51:26 -0800 Subject: [PATCH 2/3] remove set for compat with IE --- packages/core/parcel-bundler/src/builtins/hmr-runtime.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/parcel-bundler/src/builtins/hmr-runtime.js b/packages/core/parcel-bundler/src/builtins/hmr-runtime.js index 6df54bcd895..766bb1592ee 100644 --- a/packages/core/parcel-bundler/src/builtins/hmr-runtime.js +++ b/packages/core/parcel-bundler/src/builtins/hmr-runtime.js @@ -28,7 +28,7 @@ if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') { var protocol = location.protocol === 'https:' ? 'wss' : 'ws'; var ws = new WebSocket(protocol + '://' + hostname + ':' + process.env.HMR_PORT + '/'); ws.onmessage = function(event) { - updatedAssets = new Set(); + updatedAssets = {}; var data = JSON.parse(event.data); @@ -150,10 +150,10 @@ function hmrAccept(bundle, id) { return hmrAccept(bundle.parent, id); } - if (updatedAssets.has(id)) { + if (updatedAssets[id]) { return; } - updatedAssets.add(id); + updatedAssets[id] = true; var cached = bundle.cache[id]; bundle.hotData = {}; From 385680fd8828283361b116373758fef80237ac38 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Mon, 25 Feb 2019 13:07:14 +0100 Subject: [PATCH 3/3] Add test --- packages/core/integration-tests/test/hmr.js | 31 +++++++++++++++++++ .../test/integration/hmr-circular/index.js | 9 ++++++ .../test/integration/hmr-circular/local.js | 4 +++ 3 files changed, 44 insertions(+) create mode 100644 packages/core/integration-tests/test/integration/hmr-circular/index.js create mode 100644 packages/core/integration-tests/test/integration/hmr-circular/local.js diff --git a/packages/core/integration-tests/test/hmr.js b/packages/core/integration-tests/test/hmr.js index 6e5a91ce2ee..9579ef502cb 100644 --- a/packages/core/integration-tests/test/hmr.js +++ b/packages/core/integration-tests/test/hmr.js @@ -287,6 +287,37 @@ describe('hmr', function() { assert.deepEqual(outputs, [3, 10]); }); + it('should work with circular dependencies', async function() { + await ncp( + path.join(__dirname, '/integration/hmr-circular'), + path.join(__dirname, '/input') + ); + + b = bundler(path.join(__dirname, '/input/index.js'), { + watch: true, + hmr: true + }); + let bundle = await b.bundle(); + let outputs = []; + + await run(bundle, { + output(o) { + outputs.push(o); + } + }); + + assert.deepEqual(outputs, [3]); + + await sleep(100); + fs.writeFile( + path.join(__dirname, '/input/local.js'), + "var other = require('./index.js'); exports.a = 5; exports.b = 5;" + ); + + await nextEvent(b, 'bundled'); + assert.deepEqual(outputs, [3, 10]); + }); + it('should call dispose and accept callbacks', async function() { await ncp( path.join(__dirname, '/integration/hmr-callbacks'), diff --git a/packages/core/integration-tests/test/integration/hmr-circular/index.js b/packages/core/integration-tests/test/integration/hmr-circular/index.js new file mode 100644 index 00000000000..72533c84aa2 --- /dev/null +++ b/packages/core/integration-tests/test/integration/hmr-circular/index.js @@ -0,0 +1,9 @@ +var local = require('./local'); + +function run() { + output(local.a + local.b); +} + +run(); + +module.exports = 'value'; diff --git a/packages/core/integration-tests/test/integration/hmr-circular/local.js b/packages/core/integration-tests/test/integration/hmr-circular/local.js new file mode 100644 index 00000000000..3bb6f4669b5 --- /dev/null +++ b/packages/core/integration-tests/test/integration/hmr-circular/local.js @@ -0,0 +1,4 @@ +var other = require('./index.js'); + +exports.a = 1; +exports.b = 2;