google / j2cl

Java to Closure JavaScript transpiler
Apache License 2.0
1.23k stars 144 forks source link

Possible misunderstanding for @JSType exposed classes #116

Closed kschrage closed 2 years ago

kschrage commented 3 years ago

In my former GWT project we used @JSType-annotaded classes to access the java-coded business logic from a TypeScript-project (instantiating, calling methods on it).

After migrating to j2cl I cannot see any of the JSTyped-classes. If my understanding is correct they are only visible until closure compiler comes to action.

Am I right with this? Case if, what's the best practise to make the types survive the compiler? Plan is to have JS-Files to include in my webapp that make the types available to be used from JS/TS.

Thanks for any help Klemens

kschrage commented 3 years ago

I was able to make some progress with goog.exportSymbol and goog.exportProperty but I'd like to have all the explicit @JSType-d types available automatically. Maybe there's a compiler flag?

rluble commented 3 years ago

What most of our users do run the closure compiler on all of the code (from J2CL, TS, JS). That way the whole application is optimized together.

niloc132 commented 3 years ago

The open source GWT/J2CL community (https://gitter.im/gwtproject/gwt and https://gitter.im/vertispan/j2cl) is discussing an annotation processor that will generate exportSymbol and other calls so that closure emits the expected code, along with some other tools such as to make it easier to access es6 modules, etc. We've found that generating a .native.js file works for this, or if one already exists, a new plain .js file can also export it correctly, but generally agree that this doesn't belong in J2CL itself (either as I described in .js inputs, or in closure flags).

The only way it makes sense to me to have it in J2CL is if it is possible to deliberate emit some closure jsdoc annotations like @export, like other jsdoc annotations are emitted - but since we can generate plain JS that has this effect (manually or via an annotation processor), this seems to not be required?

kschrage commented 3 years ago

Ok, that matches my observations. So I‘ll try my luck with a custom annotation processor for the jstypes of my project. I don‘t think that I need the „big“ approach here. Thanks for all the clarification.

Now I do see the difficulties providing a sufficient GWT replacement on top of J2CL.

gkdn commented 3 years ago

@niloc132 keep in mind that letting libraries decide what to export is problematic and if you generate goog.export with native.js that will be the result. I think you should consider alternative generation options; e.g. using app level config files. If you really want to go with annotations, at least consider generating regular js files and not goog.require'ing them anywhere. After that the app can chose which ones to include.

niloc132 commented 3 years ago

Strongly agreed, this is not optimal, as you end up with unoptimizable code, bigger stuff elsewhere (This is one of my gripes about web components...). This is one of the reasons i'm working to get es6 modules seamlessly working with j2cl output so closure can process them all together.

That said, one of the main premises of the npm is that you get the already-packed file and webpack or whatnot will just combine all the files, do some simple treeshaking, not recompile each library on its own (or the whole world). I have seen lots of projects using closure output in the form of a library, but rarely ("never" would more accurately reflect my experience) do they take more than one closure-compiled dependency and re-compile it with just the required entrypoints, exports, etc.

AugustNagro commented 3 years ago

@niloc132 Can you elaborate on how

We've found that generating a .native.js file works for this, or if one already exists, a new plain .js file can also export it correctly

works? I have some web components that are being elided. I'm new to using J2CL, not even sure yet where the documentation for goog.require is.

HJWAJ commented 2 years ago

I'm new to J2CL and have the same demand that to access the java-coded business logic from a TypeScript-project.

After some work around I find there's one thing called goog.exportSymbol which solve my problem.

For example, the helloworld sample from getting-started samples, suppose I need to access the sayHello function from external TS project, I need to add this line

goog.exportSymbol('j2cl.samples.hello.sayHello', sayHello);

Then after imported the helloworld.js I can call j2cl.samples.hello.sayHello() to run the sayHello function.

Am I right?

gkdn commented 2 years ago

Yes, that's correct. You can see the the goog.exportSymbol documentation here for more examples: https://google.github.io/closure-library/api/goog.html