-
Notifications
You must be signed in to change notification settings - Fork 109
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
tsickle fails on RxJS due to "body of a goog.module cannot use throw" #420
Comments
RxJS has definitely been the most troublesome library for us, because it really pushes the edges of legal TypeScript. That said, it's a critical dependency of ng2 and we use it with tsickle within Google so it is possible to make it work. For this specific issue it looks like we worked around this by locally patching RxJS to wrap the code in an IIFE: // Workaround error: The body of a goog.module cannot use throw.
// Wrap in IIFE
(function () {
if (!root) {
throw new Error('RxJS could not find any global context (window, self, global)');
}
})(); I think the proper fix would be to make tsickle introduce the IIFE itself, or to fix the Closure compiler to accept this code. I'm not exactly sure why it rejects it anyway. |
I've contacted the Closure authors about why this is illegal; I'll get back to you with their response. |
When I take another swing at this (perhaps tomorrow) I'll work around this specific one with the IIFE, and see what pops up next. |
Further work finds that there are really only a few remaining problems! https://github.com/kylecordes/tsickle-fiddling/tree/build-rxjs 1) Closure "The body of a goog.module cannot use throw."Details of the warning:
This repo has a workaround for this problem. It simply comments out the line of Proposed solution: rather than wait for the Closure team to possibly relieve 2) Dependency problem with Observable.empty()Consuming application code must do: I don't have a proposed solution for this one yet. I don't know if this problem 3) Array access TypeScript constructThe following construct appears in the TypeScript code:
Tsickle passes the important bit through essentially unchanged, Closure warns about it:
This one is an open question: Is this a mismatch of the type systems? A missing So there are a few problems, but only a few - on a pile of TypeScript code that probably stretches tsickle and Closure pretty well. |
As promised, I asked about #1. It sounds like the error is related to the confusing behavior of throw at the top level with modules -- whether it aborts the current module or all JS processing. I think RxJS should not explicitly check for this case and just assume one of those globals exists. If all three don't exist then RxJS will fail anyway (due to the value it gets being undefined) which is like the throw. #2 is one of those problems I alluded to about how RxJS is the hardest code for us. That "/add/" thing is a super weird pattern seen only here. If you have a specific error message it'd help diagnose it further. #3 is using an ES6 computed name. See http://exploringjs.com/es6/ch_classes.html "Computed method names". I am not sure how this works in the Closure world. |
For "throw": I wonder if that project would accept a PR to either wrap it or remove it, or whether such a thing be set aside unless there is a consensus of interest in Closure compatible RxJS. For the /add/ thing: I've been following this a long time. A good part of my "day job" is teaching people Angular, which typically means were also teaching them TypeScript and RxJS and the observable concept all on-the-fly. I've gotten pretty good at a comprehensive explanation of what the /add/ thing does and why it does it and why it is needed and why it might be able to go away in the future. In my repo, I commented out the import line from the (nearly trivial) main.ts:
Then ran a build to get the following warning:
I spent some time trying to track down why this happens. I couldn't diagnose anything specific, other than that the dependency resolution and traversal is missing this specific link somehow. Of course if I imported "Rx" at the top this error goes away, but then I'm accidentally pulling in all of Rx which defeats the purpose of this exercise in the first place. It's possible that with some experimentation adding such an import at exactly the right place in the consuming code (rxjs/Notification.ts) might dodge the problem. For the computed name: I wonder if there is some different way to achieve this that might at least dodge the Closure warning. I see it's been discussed: google/closure-compiler#1737 |
Closure compiler does not allow this. We need this modification to use RxJS in Angular projects. Addresses angular/tsickle#420
The |
What is your motivation for wanting to run rxjs through tsickle? They already have local testing within the repo that their code is closure-compatible. |
@alexeagle My initial motivation was to see whether any better (smaller) result was possible from Closure, if provided with a version of that has Closure JSDocs. I have not looked at their test for compatibility, but as I recall their JSDocs are not valid JSDocs, Rather they are only even accepted it all by Closure if you let it spew a bunch of warnings but then disable seeing those warnings. Therefore my second motivation was to try to get more of the stack of tools to compile cleanly without warnings (and not just by hiding them). This is probably a pointless windmill to tilt at though. I had done so simply because Angular only has this one major dependency, responsible for a meaningful chunk of compiled output size. So lacking knowledge of how much it might output size, I was hoping to find out by making it work. (I assume that correct Closure full compatibility with types in JSDocs, enables more complete Closure optimizations, and what it can do if it sees and ignores a bunch of warnings.) |
1) don't throw at top-level scope. Closure compiler does not allow this if a goog.module statement is present in the file. We need this modification to use RxJS with angular/tsickle. Addresses angular/tsickle#420 2) refactor the conditional logic for finding the root object See alexeagle/closure-compiler-angular-bundling#15 Closure seems to statically reduce the existing code and eliminates the conditional, making it always throw.
We don't run closure compiler with type-aware optimizations yet. We'll have to have full tsickle-generated typing when/if we do that. We're still figuring out how to roll that out internally. |
1) don't throw at top-level scope. Closure compiler does not allow this if a goog.module statement is present in the file. We need this modification to use RxJS with angular/tsickle. Addresses angular/tsickle#420 2) refactor the conditional logic for finding the root object See alexeagle/closure-compiler-angular-bundling#15 Closure seems to statically reduce the existing code and eliminates the conditional, making it always throw.
For 3) it looks like CC could potentially handle this situation since the Symbol is a const but it doesn't for now: I think a patch to the compiler is possible for this. I honestly don't see the point of this code:
It seems like someone just wanted to use fancy computed properties/symbols. Can someone explain the use of this? In general, computed properties will not work with CC well as it cannot statically analyze these. For 2) I thought Typescript drops imports that are not used in source? For example type only imports. Perhaps I am wrong, just remember hearing this. |
With a lot of tweaking of the right config in the right place, this repo branch gets most of the way to tsickling RxJS:
https://github.com/kylecordes/tsickle-fiddling/tree/build-rxjs
I wish the steps to get here were smaller, of course, but it's quite easy to run, or just read on:
That file, emitted by tsickle:
I'm not sure where to go from here, but if I make the assumption "the goal of tsickle is to take most valid TypeScript code and make it valid properly typed Closure code", then the above seems like a bug or missing feature in tsickle. With that fig leaf as an excuse to enter this as an issue... here's what I'm trying to figure out:
The text was updated successfully, but these errors were encountered: