Giter Club home page Giter Club logo

Comments (9)

niloc132 avatar niloc132 commented on June 9, 2024

Another option: https://github.com/treblereel/gwt3-processors experimentally makes use of an annotation processor to emit a .native.js (or .js file? its been a while, I don't recall) to emit goog.exportSymbol/goog.exportProperty calls, which are functionally equivalent to the @export jsdoc.

Emitting @export when generating JS is risky (as in option 2/3), since you are only transpiling a java library in isolation, with no knowledge of how it will be used in the downstream "application". GWT 2.x doesn't do this either btw, any @JsType(isNative=false) will not be exported unless -generateJsInteropExports is passed at compile time. The goog.exportSymbol/goog.exportProperty calls do not need to be in the same JS file where the type/member was declared, allowing this decision to be made "downstream" of where the @JsType was defined.

Some care must be taken - exportProperty (or even @export) effectively doesn't seem to work on actual properties, as it exports the current value rather than a reference to the existing field/accessor. We've experimented in trying to find a better way to resolve this, but not yet talked to the closure-compiler folks about what might be wrong here.

from j2cl.

kohlschuetter avatar kohlschuetter commented on June 9, 2024

@niloc132 From my tests, google.exportSymbol on the class is not equivalent to @export on the class methods, as the exportSymbol call doesn't transitively apply to its members (it would have to apply to the prototype members since no instance of the class was instantiated).

The point is exactly that I want these accessible regardless of what j2cl thinks is being used at runtime. This is essential for building libraries (the final product may still be optimized through a separate pipeline)

For my current testing, I'm using a combination of google.exportSymbol (for the class) plus option 2 (modifying JavaScriptImplGenerator). I'd actually prefer proper code to be generated instead of depending on google.exportSymbol, which under the hood uses execScript to declare the path components. Generated JavaScript code could optimize that, too.

So, ideally, one would have a Java annotation @JsExport that can be used for the class as well as for any fields and methods, and j2cl would automatically generate code as requested.

The annotation could have a boolean property that indicates whether members are automatically exported as well, or not, and a boolean property to disallow export (i.e., export=false).
It could also have a property to specify the name, which could default to the Java class name.

Something like this:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Documented
public @interface JsExport {
  boolean export() default true;
  boolean includeMembers() default false;
  String name() default ""; // use Java name by default (for classes, use fully-qualified name)
}

from j2cl.

rluble avatar rluble commented on June 9, 2024

Unreachable public methods are optimized away by design. Applications with J2CL + jscompiler are compiled under a whole world assumption to produce small "binaries". Otherwise lots of public methods in the libraries and all the code reachable to those would be in the binary, defeating the purpose.

You can export out of the binary as mentioned above using goog.exportSymbol and goog.exportProperty. That being said I have no experience in writing application code.

from j2cl.

kohlschuetter avatar kohlschuetter commented on June 9, 2024

@rluble Would you be open to a PR?

goog.exportSymbol does NOT solve the issue, as I explained above.

from j2cl.

gkdn avatar gkdn commented on June 9, 2024

@kohlschuetter goog.exportSymbol("hello.world", HelloWorld); exports the constructor object, not its properties. Each property is individually considered for dead code removal.

Please see details here.

from j2cl.

kohlschuetter avatar kohlschuetter commented on June 9, 2024

@gkdn Yes, exactly, that's the problem.

Right now, we throw the problem from j2cl over the fence to closure-compiler, where we rely that whatever dependency logic remains from closure-library will do "the right thing", which it obviously can't because from its perspective it doesn't even know Java exists...

I had hoped that there would be an easy way to declare what I want to export from the Java side, by means of annotation.

Having said that, it's probably quite easy for me to fix this for my fork. I just wonder if this is something you'd accept as a fix.

from j2cl.

gkdn avatar gkdn commented on June 9, 2024

Sorry I don't understand what the problem is and how it is related to JsCompiler doesn't understand from Java (though actually that is not true, JsCompiler understands J2CL). The code there is doing the right thing; the behavior in handwritten JavaScript and J2CL/Java generated code are same; each class and its properties are different candidates for dead code pruning; that has nothing to do with Java or JavaScript.

Also keep in mind that you don't need to export anything explicitly unless they are used outside of your application (javascript+java) boundary. What you are doing with goog.exports is telling the optimizer what should be accessible from outside of your app (i.e. due to the code not seen by optimizer). If your javascript code is seen with the optimizer, you also don't need that.

(And we cannot accept such a PR, since it will completely defeats dead code pruning)

from j2cl.

kohlschuetter avatar kohlschuetter commented on June 9, 2024

OK, I understand this is out of scope for your project. I'm trying to use j2cl to build JavaScript code that can be reused beyond a monolithic j2cl-controlled application, that's all. Once I have a working environment that demonstrates the utility of this annotation, I will keep you posted in this issue. (I'm not proposing to use the solution in Option 2, by the way, that approach is obviously too broad)

from j2cl.

kohlschuetter avatar kohlschuetter commented on June 9, 2024

@gkdn see #220

from j2cl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.