First you need to install updated build tools that does not copy the */public/
assets into
the directory used by j2cl compile. To install build tools locally do:
> git clone https://github.com/realityforge/j2cl.git
> cd j2cl
> git checkout NoCopyPublicAssets
> mvn clean install
- Consider compiling react with closure-compiler
- Experiment with Bazel - https://github.com/bazelbuild/rules_closure
These are short-hand notes of the changes that were needed to get this "working".
- Add both
.java
and.class
files for annotation libraries. GWT2.x only required .class files and never processed them unless on source code path. - Annotation libraries now need to compilable under j2cl - previously not the case. Primarily this impacted
libraries such as
com.google.code.findbugs:jsr305:jar
. It uses several jre only features so instead of trying to fix that library I just extracted a j2cl compatible libraryorg.realityforge.javax.annotation:javax.annotation:jar
that included a few commonly used annotations (i.e.@Nonnull
,@Nullable
and@Generated
). A similar approach was taken for jetbrains annotations -org.realityforge.org.jetbrains.annotations:org.jetbrains.annotations:jar:1.0.0
- As annotation processors were moved off the classpath onto processor classpath.
- Some annotation processors had not been shaded and now needed to be. Previously when annotation processors were only on the classpath, each module would only have a processor and it deps on the classpath if it was needed. However due to limitations of some tooling (hello Intellij IDEA+maven), sometimes when adding to processor path, the processor would be visible to multiple compiles and if the processors have incompatible dependencies this would be an issue.
- The
@JsConstructor
annotation needed to be added to the constructor of thereact4j.core.NativeComponent
class and to the constructors of all subclasses, including those generated by the annotation processor. This is to satisfy J2CL which has stricter requirements with respect to the jsinterop annotations. @JsType( isNative = true )
to@JsType( isNative = true, namespace = JsPackage.GLOBAL, name = "Object" )
In GWT2.x if the objects were created by the javascript library and passed to java it did not matter.- Change the namespace the jsinterop typing of the
React
class from@JsType( isNative = true, namespace = "React", name = "Component" )
to@JsType( isNative = true, namespace = JsPackage.GLOBAL, name = "React.Component" )
as J2CL only considers types with a namespace ofJsPackage.GLOBAL
to be capable of being externs. - Rework the way compile time constants are processed to be compatible with j2cl - see https://github.com/realityforge/braincheck/commit/832c2e7e862196f72afd5569695041d331d9aae2
- Find and include externs.
- Add defines to the source projects (react4j+braincheck+arez) that required the defines from a
ArezConfig.native.js
file so that the compile constants were available to closure compiler.
- No way to convert Enums into integers?
- Raw: 30598 (J2CL) vs 36826 (GWT 2.8.2) ~ 83%
- Arez: 63316 (J2CL) vs 70358 (GWT 2.8.2) ~ 90%
- Arez (with patched Arez): 62989 (J2CL) vs 70358 (GWT 2.8.2) ~ 90%
- Dagger: 66418 (J2CL) vs 75335 (GWT 2.8.2) ~ 88%
The patched Arez mostly involved converting interfaces into @JsFunction
interfaces. This increases sizes under
GWT 2.8.2 and decreases sizes under J2CL. Thus it has not been applied to master. See the associated
Pull Request.
-
Document
namespace
parameter value"<window>"
of@JsType
. Consider suggeating Extraction of jsinterop, javaemul and jre libraries to be moved outside GWT repository. Here is the description from Colinis an "escape hatch" of sorts, undocumented but supported, which lets you say "just let me run without any namespace at all" in gwt, GLOBAL means a $wnd. prefix (in j2cl it means goog.global. prefix) see jsinterop.base.Js for a few examples of