Skip to content
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

Avoid parsing JS files when building a bundle #4007

Merged

Conversation

niloc132
Copy link
Contributor

@niloc132 niloc132 commented Nov 3, 2022

This avoids the case where LazyParsedDependencyInfo.getLoadFlags() might parse the entire file to check if a JS file can be bundled as a Closure or ES6 module.

Fixes #4006

This avoids the case where LazyParsedDependencyInfo.getLoadFlags() might
parse the entire file to check if a JS file can be bundled as a Closure
or ES6 module.

Fixes google#4006
@lauraharker lauraharker self-assigned this Nov 4, 2022
@lauraharker
Copy link
Contributor

I'm trying to figure out why @googlebot hasn't run for this PR - usually it automatically runs to check if you've signed a Contributor's Licensing Agreement. Example: #3833 (comment).

I'll try to retrigger @googlebot. Meanwhile, if you haven't already signed at https://cla.developers.google.com/, please go ahead and do so.

@lauraharker
Copy link
Contributor

Ok, I reran the CLA check and looks like you've already signed, thanks.

I've imported this for some internal testing.

@@ -140,6 +140,13 @@ abstract static class Builder {
/** Whether the symbol is provided by a module */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should isModule() and isGoogModule() always return the same thing?

If so let's be more explicit about that - could we make DependencyInfo.Base.isModule final? The only overrides I see are in JSChunk.java and DependencyMap.java.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, but I'm not totally sure that it is always the same thing. From JSChunk.isModule():

  @Override
  public boolean isModule() {
    // NOTE: The meaning of "module" has changed over time.  A "JsChunk" is
    // a collection of inputs that are loaded together. A "module" file,
    // is a CommonJs module, ES6 module, goog.module or other file whose
    // top level symbols are not in global scope.
    throw new UnsupportedOperationException();
  }

I was concerned that, despite the implementation in DependencyInfo.Base.isModule() explicitly checking for goog modules, that this JsChunk implementation required that isModule continue to throw. The comment seems to be generally inaccurate, or at least in conflict with other implementations, so I only changed DependencyInfo.Base.isModule() to take the fast path (and skip parsing), but stil permit JSChunk to throw in this specific case.

I didn't notice at the time (but am seeing now) that JSChunk also throws for getLoadFlags(), so perhaps I'm being overly cautious. Will be guided by your knowledge/preference here - if I'm being too careful about code that I can't see (that assumes isModule() might in fact be referring to commonjs/es6/goog as the comment describes), yes, we can probably delete JSChunk.isModule().

--

I can see no source file with the name DependencyMap.java, nor type with that name - typo, or internal class I can't see?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reasonably confident that the JSChunk comment is just misleading, and isModule should really mean isGoogModule.

that comment and the isModule method were both added back in 2014 in 57bbf72. That commit is adding goog.module support. At the time, Closure Compiler already had some support for CommonJS modules (5ef7a8a) but not ES modules.

If you're willing to completely replace isModule with isGoogModule that sounds good to me. I don't see too many usages even if I include internal-only classes.


DependencyMap.java is an internal class yes, my bad. I'll just update it when importing your change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed that method, only found in tests, a javadoc comment, and one invocation that didn't record the value, and may have been a mistake. Along the way I removed the Base abstract class as it only had one method left, and pushed that up to the interface as a default method - at least in the public git repo, there are no overloads of it, so probably minimal impact.

I think this can be resolved, but will leave it open for you to confirm.

@@ -140,6 +140,13 @@ abstract static class Builder {
/** Whether the symbol is provided by a module */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reasonably confident that the JSChunk comment is just misleading, and isModule should really mean isGoogModule.

that comment and the isModule method were both added back in 2014 in 57bbf72. That commit is adding goog.module support. At the time, Closure Compiler already had some support for CommonJS modules (5ef7a8a) but not ES modules.

If you're willing to completely replace isModule with isGoogModule that sounds good to me. I don't see too many usages even if I include internal-only classes.


DependencyMap.java is an internal class yes, my bad. I'll just update it when importing your change.

@lauraharker
Copy link
Contributor

Update: I'm looking at a few test failures in our internal test suite. Currently investigating whether they're caused by some internal-only changes I made/failed to make, or something in this PR.

@lauraharker
Copy link
Contributor

Another update:

I'm currently working on trying to avoid using the regex parser for compilations that need to fully parse each input file anyway. So the goals of these two changes don't conflict, but I still need to verify my implementation won't mess up your PR or vice versa.

@niloc132
Copy link
Contributor Author

Thanks for the update, I appreciate it. Let me know if it makes more sense to merge your changes and have me try to rework this instead of you managing both.

We're trying to pick up the typed_ast feature for ADVANCED compiles without re-parsing everything on small changes, but have a sort of simplified version for BUNDLE that serializes the results of the regex parser to avoid even redoing that parsing work on the bulk of a given library. While this is working, we're still figuring out typed_ast, so redoing some of this work wouldn't be a big impediment if it helps generally improve performance.

@lauraharker
Copy link
Contributor

Thanks for all your patience - this change looks good to go, no conflicts with what I'm working on. I've gotten it approved in internal code review and plan to submit it on Monday.

@copybara-service copybara-service bot merged commit 6bb9dd8 into google:master Jan 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Compilation level BUNDLE always fully parses file instead of only using regex parser
2 participants