From 3d1e4bac42e386c6f976b664a9ceb97bd7bc15ec Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Sat, 12 Jan 2019 00:26:05 +0100 Subject: [PATCH 1/5] Fix HMR failure with js error on load --- .../core/parcel-bundler/src/builtins/prelude.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/core/parcel-bundler/src/builtins/prelude.js b/packages/core/parcel-bundler/src/builtins/prelude.js index 9dccee3e5b3..2a71f71d2f0 100644 --- a/packages/core/parcel-bundler/src/builtins/prelude.js +++ b/packages/core/parcel-bundler/src/builtins/prelude.js @@ -77,8 +77,16 @@ parcelRequire = (function (modules, cache, entry, globalName) { }, {}]; }; + var error; for (var i = 0; i < entry.length; i++) { - newRequire(entry[i]); + try{ + newRequire(entry[i]); + } catch(e){ + // Save first error but execute all entries + if(!error){ + error = e; + } + } } if (entry.length) { @@ -103,5 +111,12 @@ parcelRequire = (function (modules, cache, entry, globalName) { } // Override the current require with this new one + parcelRequire = newRequire; + + if(error){ + // throw error from earlier, _after updating parcelRequire_ + throw error; + } + return newRequire; }) From 19664ff1d887614d31601078aa64c5fea95f1eaa Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Sat, 12 Jan 2019 01:20:02 +0100 Subject: [PATCH 2/5] Add test --- packages/core/integration-tests/test/hmr.js | 49 ++++++++++++++++++- packages/core/integration-tests/test/utils.js | 1 + 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/core/integration-tests/test/hmr.js b/packages/core/integration-tests/test/hmr.js index 7ea84ce743b..ca1c92d5c3f 100644 --- a/packages/core/integration-tests/test/hmr.js +++ b/packages/core/integration-tests/test/hmr.js @@ -1,7 +1,8 @@ const assert = require('assert'); const fs = require('@parcel/fs'); const path = require('path'); -const {bundler, run, rimraf, ncp} = require('./utils'); +const {bundler, run, rimraf, ncp, prepareBrowserContext} = require('./utils'); +const vm = require('vm'); const {sleep} = require('@parcel/test-utils'); const WebSocket = require('ws'); const json5 = require('json5'); @@ -287,6 +288,52 @@ describe('hmr', function() { assert.deepEqual(outputs, [3, 10]); }); + it('should accept HMR updates in the runtime after an initial error', async function() { + await fs.mkdirp(path.join(__dirname, '/input')); + fs.writeFile( + path.join(__dirname, '/input/index.js'), + 'throw new Error("Something");\noutput(123);' + ); + + b = bundler(path.join(__dirname, '/input/index.js'), { + watch: true, + hmr: true + }); + let bundle = await b.bundle(); + + let outputs = []; + let errors = []; + + var ctx = prepareBrowserContext(bundle, { + output(o) { + outputs.push(o); + }, + error(e) { + errors.push(e); + } + }); + vm.createContext(ctx); + vm.runInContext( + `try { + ${(await fs.readFile(bundle.name)).toString()} + } catch(e) { + error(e); + }`, + ctx + ); + + assert.deepEqual(outputs, []); + assert.equal(errors.length, 1); + assert.equal(errors[0].message, 'Something'); + + await sleep(100); + fs.writeFile(path.join(__dirname, '/input/index.js'), 'output(123);'); + + await nextEvent(b, 'bundled'); + assert.deepEqual(outputs, [123]); + assert.equal(errors.length, 1); + }); + 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/utils.js b/packages/core/integration-tests/test/utils.js index e2f78fd517a..899135bf306 100644 --- a/packages/core/integration-tests/test/utils.js +++ b/packages/core/integration-tests/test/utils.js @@ -281,3 +281,4 @@ exports.deferred = deferred; exports.rimraf = rimraf; exports.ncp = ncp; exports.normaliseNewlines = normaliseNewlines; +exports.prepareBrowserContext = prepareBrowserContext; From 3f0c22ce21c3d5e5e757b1e71e391361fe5f8759 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Sat, 12 Jan 2019 01:22:22 +0100 Subject: [PATCH 3/5] Format --- packages/core/integration-tests/test/hmr.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/integration-tests/test/hmr.js b/packages/core/integration-tests/test/hmr.js index ca1c92d5c3f..15de0d6639f 100644 --- a/packages/core/integration-tests/test/hmr.js +++ b/packages/core/integration-tests/test/hmr.js @@ -315,10 +315,10 @@ describe('hmr', function() { vm.createContext(ctx); vm.runInContext( `try { - ${(await fs.readFile(bundle.name)).toString()} - } catch(e) { - error(e); - }`, + ${(await fs.readFile(bundle.name)).toString()} + } catch(e) { + error(e); + }`, ctx ); From a17d43d114922a191dc62f30d59602dc7749ef72 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Fri, 8 Feb 2019 19:58:30 +0100 Subject: [PATCH 4/5] Export prepareBrowserContext in test-utils --- packages/core/test-utils/src/utils.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/test-utils/src/utils.js b/packages/core/test-utils/src/utils.js index 10a8cd1649f..ce76f19b12d 100644 --- a/packages/core/test-utils/src/utils.js +++ b/packages/core/test-utils/src/utils.js @@ -289,6 +289,7 @@ exports.symlinkPrivilegeWarning = symlinkPrivilegeWarning; exports.bundler = bundler; exports.bundle = bundle; exports.run = run; +exports.prepareBrowserContext = prepareBrowserContext; exports.assertBundleTree = assertBundleTree; exports.nextBundle = nextBundle; exports.deferred = deferred; From bf2157137996157874a167d5875bef4141772408 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Wed, 6 Mar 2019 08:25:53 -0800 Subject: [PATCH 5/5] Cleanup --- .../core/parcel-bundler/src/builtins/prelude.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/core/parcel-bundler/src/builtins/prelude.js b/packages/core/parcel-bundler/src/builtins/prelude.js index 2a71f71d2f0..db17e45c58d 100644 --- a/packages/core/parcel-bundler/src/builtins/prelude.js +++ b/packages/core/parcel-bundler/src/builtins/prelude.js @@ -5,9 +5,7 @@ // // anything defined in a previous bundle is accessed via the // orig method which is the require for previous bundles - -// eslint-disable-next-line no-global-assign -parcelRequire = (function (modules, cache, entry, globalName) { +(function (modules, cache, entry, globalName) { // Save the require from previous bundle to this closure if any var previousRequire = typeof parcelRequire === 'function' && parcelRequire; var nodeRequire = typeof require === 'function' && require; @@ -79,11 +77,11 @@ parcelRequire = (function (modules, cache, entry, globalName) { var error; for (var i = 0; i < entry.length; i++) { - try{ + try { newRequire(entry[i]); - } catch(e){ + } catch (e) { // Save first error but execute all entries - if(!error){ + if (!error) { error = e; } } @@ -113,10 +111,8 @@ parcelRequire = (function (modules, cache, entry, globalName) { // Override the current require with this new one parcelRequire = newRequire; - if(error){ + if (error) { // throw error from earlier, _after updating parcelRequire_ throw error; } - - return newRequire; })