虽然我喜欢Scala的语言和Scala.js这个项目,但我对最终JS包的大小有点失望,即使在fullOptJS模式下也是如此。
我迫切需要创建一个用于浏览器的小型库。>150kb是一个很大的要求,可以说像BuckleScript/ReasonML这样的类似工具承诺快速执行和微小的捆绑包。
在可预见的未来,Scala.js会开始生产更小的捆绑包吗?
简短的回答:不太可能。
在设计语言时,总是需要做出权衡。特别是,跨 JavaScript 和另一个目标交叉编译一种语言通常会导致一系列或多或少相互冲突的目标。例如,生成"惯用的,可读的JavaScript"通常与生成"高度优化的JavaScript"不一致。
在这个空间中,Scala的主要设计目标是.js重要性降序排列:
- 与 JavaScript 的互操作性:能够调用和被 JavaScript 代码/库调用。 与 Scala/JVM
- 的兼容性:除非使用固有的特定于平台的 API(例如线程),否则相同的 Scala 代码应使用 Scala/JVM 和 Scala.js 进行编译,并以相同的方式运行。
- 运行时性能:生成的代码应尽可能快。 代码
- 大小:生成的代码应尽可能小。
虽然代码大小绝对是一个问题,但如您所见,它在主要设计目标列表中的位置相当低。这意味着代码大小问题通常会让位于列表中的其他问题。
特别是,它经常与与Scala/JVM的兼容性要求不一致。事实上,Scala有一个相当大的标准库,特别是集合,并且该库的许多部分相互依赖。这意味着一旦你使用,比如说,一个ScalaList
,你的代码需要标准Scala集合库的很大一部分。stdlib 的这一部分使大多数非平凡的 Scala.js 程序的重量超过 150 KB。
由于上述条件(设计目标+集合库相互依赖)在可预见的未来不太可能改变,因此Scala.js也不太可能突然产生更少的代码。
严格来说,编写一个 Scala.js 应用程序可以只产生 10 KB 或更多。但为了做到这一点,你必须非常小心,不要使用集合库的任何部分。您应该在任何地方使用js.Array
s、js.FunctionN
s 和js.Promise
s,而不是List
s,例如=>
函数和Future
s。在这一点上,Scala.js不再是Scala,因此你最好使用另一种语言(例如BuckleScript)。