vue模块化和非模块化
TL; DR:本文介绍了锡兰运行时和分布中的模块化更改,以使其在运行时更轻。 如果只需要结果,请跳至“ 最终运行时依赖项”部分。
锡兰从一开始就采用模块化架构 。 不仅适用于编写模块的Ceylon用户,而且适用于Ceylon发行版中。 从历史上看,我们过去很少有模块,这些模块直接与单独的Git项目相关。 添加新模块意味着新的存储库以及构建中的许多更改。 自然地,随着项目的发展,这些模块中的每个模块也都在增长,并获得了新的第三方依赖关系,并且通过在分发模块之间添加“更多”依赖关系,有时在一个模块中添加功能变得非常容易。较旧/已开发系统中常见的配电模块大意大利面图。
最初我们期望大多数Ceylon用户使用ceylon run
命令运行代码,所以我们认为,由于他们安装了Ceylon发行版,因此,他们依赖该发行版中的更多模块是否超出严格的要求并不重要。 这些模块无论如何都必须存在,因此不会节省任何带宽来减少那些依赖。
自然,我们错了,在Ceylon Eclipse或IntelliJ IDE之间,在OpenShift,WildFly,Vert.x或Android上运行Ceylon的人们开始只安装标准java
运行程序而无需安装发行版即可运行Ceylon。 很快变得很明显,我们不得不解开这些依赖关系以减轻运行时要求。
从历史上看,我们有以下模块:
- 其他模块使用的通用模块
- typechecker(共享的编译器前端)
- Java编译器后端
- JavaScript编译器后端
- 模块仓库系统
- JBoss模块运行时
模型模块
当实现改进的泛型时 ,我们必须在运行时添加子类型,以便能够确定is T bar
为真。 当时最简单的事情是“仅”依赖于处理语言模型和子类型的类型检查器(编译器前端)以及Java编译器后端,后者具有从JVM信息中加载语言模型的基础架构,例如作为类文件,或者在这种情况下为反射。
这实际上使运行时依赖于编译器的前端和后端,我们意识到这并不理想,因此在Ceylon 1.2开发过程中,我们提取了所有模型描述,并将其加载和子化为新的Ceylon ceylon-model
模块,但是我们没有足够的时间做更多的事情,因此由于其他原因,这些依赖关系仍然存在。
支持Java 9
在支持Ceylon中的Java 9 / Jigsaw模块的过程中 ,很明显,将我们的javalang
工具的“ fork”(我们用于javac
)保留在其原始包名称下将不再起作用,我们对其包进行了重命名并使用了有机会修剪掉我们未使用的部分Java工具。 我们还将类文件阅读器部分提取到其自己的模块中,因此我们可以在编译器外部使用它来删除对jandex
(类文件扫描器)的依赖。
最后,当我们创建ceylon jigsaw
工具(使用Ceylon模块所需的jar文件填充一个文件夹,以便在Java 9 VM上运行它)时,很明显,运行时仍然不仅依赖于编译器前端,而且Java后端,甚至在JavaScript后端,坦率地说,在大多数JVM执行中,这没有什么意义。
这些依赖关系是由于Ceylon工具提供程序API方便时(当时)已ceylon.language
模块。 由于这使您能够以编程方式为Java和JavaScript后端编译和运行Ceylon,因此它必须依赖于工具。
我们决定将Ceylon Tool Provider分成自己的模块,摆脱了从语言模块到编译器和typechecker的最终依赖关系,但是没有更多的时间为Ceylon及时摆脱JBoss Modules和Aether之类的依赖关系1.2.2。
支持Android
在Android上运行Ceylon的最初工作表明,对于普通的JVM执行甚至Java EE部署具有很小的依赖性,对于所有方法都至关重要的Android来说,这并不是一个选择。
在这一点上,我们不得不硬着头皮,使所有不需要的传递依赖项消失。
我们注意到,旧的common
模块已经成长为包括使ceylon
命令及其子命令和插件正常工作的命令行工具API 。 这又取决于ceylon doc
使用的Markdown渲染器。 将其提取到其自己的模块非常简单,因为在锡兰用户程序中从未使用过它。
接下来是我们的Shrinkwrap Resolver依赖项,我们的模块存储库系统使用该依赖项与Maven存储库进行互操作 。 这是一个胖子,它包含所有依赖项,包括一些Apache Commons模块和Eclipse Aether的过时版本。 这个胖子在我们的Maven模块中已经存在问题,该模块已经具有Aether版本,因此摆脱胖子是一个好主意。 我们还意识到,它的某些Apache Commons依赖项已经包含在我们的发行版本存储库中的胖子之外,因此也有重复的问题可以解决。
因此,我们要做的就是删除Shrinkwrap Resolver依赖项,并通过将其所有子组件合并到我们的发行版中直接使用Aether。 事实证明,由于最新版本的Aether需要使用Google Guava,因此我们的发行版的大小有所增加而不是缩小(那罐子很大)。 但是为了弥补这一点,我们将Aether依赖项设置为可选,并确保只要事先有一些编译步骤提供了可以在互操作中使用的所有Maven依赖项,就可以在没有它的情况下运行Ceylon。 ceylon fat-jar
或ceylon jigsaw
将为您做到这一点。
我们的模块存储库系统还提供了对WebDAV或Herd存储库写入的支持,这需要对Apache Http Client或Sardine的某些依赖,并且我们也使这些依赖关系成为可选,因为在运行时,您的Ceylon程序不太可能写入HTTP存储库。 只有编译器和其他工具才能执行此操作。
我们还使用抽象从语言模块中删除了对JBoss模块的依赖,因为该平台是可选的,并且从未在Android或其他平面类路径运行时使用。
最后,由于其中存在Main API
,语言模块在(更苗条的)模块存储库系统上只剩下一个依赖项,因此我们将该类移到了自己的模块中。
最终运行时依赖项
在完成所有这些修剪之后,JVM上的语言模块又恢复为要求以下传递依赖项集:
- 通用(很小,没有工具和依赖项)
- 模型(仅取决于类文件读取器)
- 类文件阅读器
因此,您的Ceylon模块将仅依赖于四个jar(这三个和language模块),它们的总大小为2.4 Mb,比最初的要小得多,并且方法的数量要少得多,大约为17148个方法。 这仍然太多了,但是可以通过诸如ProGuard之类的工具删除未使用的类来降低它。 记住这包括一个完整的语言运行时,所以它不是那么大,所有的事情考虑。
SDK变更
为了能够在Android上使用Ceylon的HTTP客户端,我们还将ceylon.net
模块从Ceylon SDK拆分为客户端和服务器模块。 否则,HTTP服务器及其依赖关系对于Android的方法数量来说是太多了。
翻译自: https://www.javacodegeeks.com/2016/07/modularity-changes.html
vue模块化和非模块化