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 a23499a4a72..46b470489db 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -1217,5 +1217,17 @@ 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( + __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)