From 9bd12c6091527f685c3d6fbf1de5b5584ade5544 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Tue, 7 May 2019 21:25:23 -0700 Subject: [PATCH 1/2] Fix assigning to exports from inside a function in scope hoisting --- .../commonjs/export-assign-scope/a.js | 4 ++++ .../commonjs/export-assign-scope/b.js | 3 +++ .../integration-tests/test/scope-hoisting.js | 12 ++++++++++ .../src/scope-hoisting/hoist.js | 22 ++++++++++++++----- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/a.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/b.js diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/a.js b/packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/a.js new file mode 100644 index 00000000000..062d1398324 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/a.js @@ -0,0 +1,4 @@ +var b = require('./b'); + +b.setValue(2); +module.exports = b.value; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/b.js b/packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/b.js new file mode 100644 index 00000000000..a0d2f196b4b --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/commonjs/export-assign-scope/b.js @@ -0,0 +1,3 @@ +exports.setValue = function (value) { + exports.value = value; +} diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index a119671bee8..4d7ee37c807 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -1204,5 +1204,17 @@ describe('scope hoisting', function() { let output = await run(b); assert.deepEqual(output, 42); }); + + it('should support assigning to exports from inside a function', async function() { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/commonjs/export-assign-scope/a.js' + ) + ); + + let output = await run(b); + assert.deepEqual(output, 2); + }); }); }); diff --git a/packages/core/parcel-bundler/src/scope-hoisting/hoist.js b/packages/core/parcel-bundler/src/scope-hoisting/hoist.js index 95d7ed2cfb3..8fdfb51a053 100644 --- a/packages/core/parcel-bundler/src/scope-hoisting/hoist.js +++ b/packages/core/parcel-bundler/src/scope-hoisting/hoist.js @@ -268,13 +268,23 @@ module.exports = { let scope = path.scope.getProgramParent(); if (!scope.hasBinding(identifier.name)) { asset.cacheData.exports[name] = identifier.name; - let [decl] = path.insertBefore( - t.variableDeclaration('var', [ - t.variableDeclarator(t.clone(identifier), right) - ]) - ); - scope.registerDeclaration(decl); + // If in the program scope, create a variable declaration and initialize with the exported value. + // Otherwise, declare the variable in the program scope, and assign to it here. + if (path.scope === scope) { + let [decl] = path.insertBefore( + t.variableDeclaration('var', [ + t.variableDeclarator(t.clone(identifier), right) + ]) + ); + + scope.registerDeclaration(decl); + } else { + scope.push({id: t.clone(identifier)}); + path.insertBefore( + t.assignmentExpression('=', t.clone(identifier), right) + ); + } } else { path.insertBefore( t.assignmentExpression('=', t.clone(identifier), right) From 0d8ea8fe3abf7a64010a4d8f2676f285720a70e8 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Wed, 8 May 2019 13:03:55 -0700 Subject: [PATCH 2/2] lint --- packages/core/integration-tests/test/scope-hoisting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index ccc7ac07564..46b470489db 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -1217,7 +1217,7 @@ describe('scope hoisting', function() { assert.equal(output.__esModule, true); assert.equal(output.default, 2); }); - + it('should support assigning to exports from inside a function', async function() { let b = await bundle( path.join(