-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CrossChunkCodeMotion introduces JS runtime error in ES2015+ #3752
Comments
Are you utilizing the |
That flag hasn't ever been viable because it doesn't create the namespace object before trying to write to it. Currently working around the runtime error by transforming all module-level |
You either need to define the namespace externally, or you can use an output wrapper:
|
To be clear, this isn't a problem with CCCM but with how the code is loaded. The compiler generates code that expects to be loaded as global scripts, if you want isolation between chunks I do think this is something that should be clearly document and likely is not. |
I've just added a wiki page to explain generating chunks for dynamic loading, including a section on how to load the chunks. https://github.com/google/closure-compiler/wiki/Chunk-output-for-dynamic-loading I got permission form @ChadKillingsworth to use his stackoverflow answer as a starting point. |
Okay, I've figured out what was going wrong. The I guess we'll just need to set our own implementation for the loader to get this working. I honestly had no clue that Example for thoroughness' sake... <html>
<head>
<script>
function loadScript(source) {
const scriptElt = document.createElement('script');
scriptElt.appendChild(document.createTextNode(source));
document.head.appendChild(scriptElt);
}
const mainSource = 'const x = 5;';
loadScript(mainSource);
const otherSource = 'console.log(x+5);';
loadScript(otherSource);
</script>
</head>
</html> While this produces a runtime error: <html>
<head>
<script>
const indirectEval = eval;
const mainSource = 'const x = 5;';
indirectEval(mainSource);
const otherSource = 'console.log(x+5);';
indirectEval(otherSource);
</script>
</head>
</html> |
Given the following code:
Compiling into ES2015
Produces the following output:
mainout.js:
otherout.js:
As you can see, the class
Base
(d
) frommain.js
has been moved to a different chunk, since it is unused in its own chunk.Unfortunately the
LocalConstant
(c
) is not available in the context ofotherout.js
, because it is declared withconst
inmainout.js
.If
main.js
is adjusted to include aexports.LocalConstant = LocalConstant;
thenconst c
becomesvar c
and therefore is available in the other module.Before ES2015
const
did not exist, so this worked without error.There are 2 possible fixes, I am not sure which is preferred:
CrossChunkCodeMotion
CompilerPass to not move theBase
class out of its chunk, because it is tied to the local variable, and therefore a part of the global cycle created by the side-effect of logging the constant.exports.LocalConstant = LocalConstant;
I am going to start looking into the first of those as a contribution, mostly just because it seems easier.
The text was updated successfully, but these errors were encountered: