From 6daf2bfa2aeda9d5702c7e492d3c4043161261a2 Mon Sep 17 00:00:00 2001 From: Christopher Allen Date: Tue, 15 Feb 2022 11:53:56 +0000 Subject: [PATCH] fix(build): Correctly handle deep export paths A problem can occur when loading chunks in a browser: although factory() will create the full exported path on $, and thus the assignment root. = factory(...) { ...; return $. } will normally be a do-nothing in every chunk except the first, if the exported path (e.g. Blockly.blocks.all) is more than one level deeper than any previously-existing path (e.g. Blockly), this will fail because root. is evaluated before calling factory(), and so the left hand side will will evaluate to a undefined reference (e.g. undefined.all) and TypeError will be thrown before the call to factory is evaluated. To fix this, call factory first and store the exports object in a variable before assigning it to the exported path. Fixes #5932. --- scripts/gulpfiles/build_tasks.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/gulpfiles/build_tasks.js b/scripts/gulpfiles/build_tasks.js index 5b9213a766c..f2409122fcd 100644 --- a/scripts/gulpfiles/build_tasks.js +++ b/scripts/gulpfiles/build_tasks.js @@ -333,6 +333,12 @@ function chunkWrapper(chunk) { const browserDeps = chunk.dependencies.map(d => `root.${d.exports}`).join(', '); const factoryParams = chunk.dependencies.map(d => d.importAs).join(', '); + + // Note that when loading in a browser the base of the exported path + // (e.g. Blockly.blocks.all - see issue #5932) might not exist + // before factory has been executed, so calling factory() and + // assigning the result are done in separate statements to ensure + // they are sequenced correctly. return `// Do not edit this file; automatically generated. /* eslint-disable */ @@ -342,7 +348,8 @@ function chunkWrapper(chunk) { } else if (typeof exports === 'object') { // Node.js module.exports = factory(${cjsDeps}); } else { // Browser - root.${chunk.exports} = factory(${browserDeps}); + var exports = factory(${browserDeps}); + root.${chunk.exports} = exports; } }(this, function(${factoryParams}) { ${chunk.factoryPreamble || FACTORY_PREAMBLE}