Comments (9)
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.
@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.
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.
@rluble Would you be open to a PR?
goog.exportSymbol
does NOT solve the issue, as I explained above.
from j2cl.
@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.
@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.
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.
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.
from j2cl.
Related Issues (20)
- Wasm sample broken HOT 2
- package listing?
- io_bazel_rules_kotlin_configured HOT 4
- How to fix the error: unused native file on Windows 11? HOT 1
- Ready to work on download file
- Wasm sample broken v2 HOT 2
- JUnit test example for wasm HOT 5
- I receive the following issue during the build. Have anyone an idea what the reason is: HOT 3
- [WASM] HashMap.computeIfAbsent doesn't work as expected HOT 1
- Can't run j2cl on Bazel 6 HOT 6
- Bazel: accidental impossible target HOT 2
- goog.reflect.sinkValue and deadcode elimination
- How to use it in vite +vue3
- Automate release/tag of the repo on green builds
- predicate is not usable by but exposed to JavaScript. HOT 3
- Support `rules_jvm_external` or `j2cl_maven_import_external` private registry HOT 1
- JRE emulation misses java.io.Externalizable
- Add dependabot to keep GitHub Actions up-to-date
- "Native JsType method '...' should be native, abstract or JsOverlay." error prevents default implementation for vanilla Java HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from j2cl.