J2Cl崛起:GWT之后的Java Web开发 - KIE


GWT已经死了,自2006年以来,Web开发发生了巨大的变化:
现在浏览器之间已经不存在相互冲突的混乱局面,但是,现代的web开发框架也远非理想。
例如,GWT的一个非常强大的优势是围绕着Maven的生态系统--这个解决方案的稳定性和可用性令人难以置信,尤其是在大团队进行大型项目工作时。

Google曾经作为GWT的主要开发者,放弃了这个项目,又开始了J2CL,可以看成是GWT的后继者,它将最佳实践提升到了一个新的水平。
他们的文档称它被用于许多高性能的项目中,如Gmail、Inbox、Docs、Slides和Calendar。

最初开发J2CL是为了在Bazel环境中使用。经过几年的努力,由Colin Alworth领导的社区发布了第一个用于Maven的J2CL公共版本:j2cl-maven-plugin。

那么让我们来看看它是什么以及它是如何工作的。

J2CL和封闭式编译器
J2CL只负责一项任务:将一组Java类转译成一组JavaScript文件。

Google的Closure Compiler负责将这组Javascripts合并成一个可执行的JS脚本,并对其进行优化和减化。

Closure Compiler在对JavaScript进行最小化和优化方面非常高效,它根本没有竞争对手。

生成我们的第一个J2CL项目
让我们从一个简单的单模块应用程序开始。幸运的是,我们可以从一个预构建的原型中生成它。如果你没有这个原型,请下载它:

mvn org.apache.maven.plugins:maven-dependency-plugin:get \
-DrepoUrl=https://repo.vertispan.com/j2cl/ \
-Dartifact=com.vertispan.j2cl.archetypes:j2cl-archetype-simple:0.19

现在可以生成一个简单应用项目:

mvn archetype:generate -DarchetypeGroupId=com.vertispan.j2cl.archetypes \
-DarchetypeArtifactId=j2cl-archetype-simple \
-DarchetypeVersion=0.19

生成的项目结构如下:

├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── org
    │   │       └── treblereel
    │   │           └── j2cl
    │   │               ├── App.java
    │   │               └── App.native.js
    │   └── webapp
    │       ├── WEB-INF
    │       │   └── web.xml
    │       ├── css
    │       │   └── simpleapp.css
    │       └── index.html
    └── test
        └── java
            └── org
                └── treblereel
                    └── j2cl
                        └── AppTest.java

- App.java是我们应用程序的一个起点,有一点我必须强调。

- App.native.js用于向Closure编译器指定如何启动我们的应用程序,因为它对此一无所知。Native.js的使用是一个非常大的话题,可以单独写一篇文章来讨论。

- AppTest.java只是一个兼容J2CL的单元测试,在HtmlUnit中运行,也可以使用ChromeDriver在真正的浏览器中运行,但需要更长时间。

- pom.xml - 这里对我们来说唯一有趣的部分是j2cl-maven-plugin部分。目前,它只包含<compilationLevel>声明,用于设置项目编译时要使用的优化级别。ADVANCED是最有效的级别,因此Closure Compiler会进行积极的重命名、去除死代码、全局内联等等。但是在某些情况下,Closure Compiler需要我们的帮助和关心--我们必须声明哪些属性或方法不应该被删除或重命名。BUNDLE不那么严格,更适合于开发,因为与ADVANCED相比,每一轮编译需要的时间更少。

运行和构建我们的j2cl应用程序
j2cl-maven-plugin允许我们在开发模式下运行我们的应用程序,具有内置的热代码重载和源码图调试功能。要启动开发模式,请在终端运行以下命令。

 mvn j2cl:watch

当应用程序启动后,在第二个终端运行以下命令。

 mvn jetty:run

不需要每次都运行'mvn clean',因为J2CL会从头开始重新编译一切,我们可以重新使用之前运行的结果。此外,还有一个选项可以在几个项目之间使用全局缓存以减少编译时间。

为了构建'.war',我们应该运行'mvn package',这里没有什么新东西,对于GWT开发者来说,一切都非常熟悉。

好吧,与GWT相比,有什么新的东西?

  • GWT模块没有了,是的,没有了模块。所以J2CL会尝试从pom.xml中编译直接和横向的依赖关系,这就是为什么我们应该给注解处理器设置 "provided scope"并遮蔽它们。
  • GWT.create也消失了
  • GWT生成器已经消失了,现在我们应该使用基于APT的生成器。
  • 我们以前使用的GWT组件和小工具呢?它们中的大多数已经被移植到了J2CL。
  • @GwtIncompatible能不能用?是的,它还在这里。

它对我们的价值是什么?
现在我们专注于将现有项目从gwt2迁移到j2cl。有很多库已经迁移到了j2cl,也有很多库支持gwt2和j2cl。 我想强调的是 elemental2-* wrappers, DominoKit, Nalu, 和许多其他库。
Gwt2已经被移植为gwtproject--一组被移植的模块。Errai框架--我们应用程序的核心组件已被重新实现为Crysknife项目。