fix(build): Correctly handle deep export paths in UMD wrapper (#5945)

* 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.<path> = factory(...) { ...; return $.<path> }

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.<path> 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.
This commit is contained in:
Christopher Allen
2022-02-22 22:04:49 +00:00
committed by GitHub
parent f1148f1732
commit 71ab146bc2

View File

@@ -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 factoryExports = factory(${browserDeps});
root.${chunk.exports} = factoryExports;
}
}(this, function(${factoryParams}) {
${chunk.factoryPreamble || FACTORY_PREAMBLE}