从 SJSIR 手动构建 JS
Build JS from SJSIR `manually`
我需要在运行时从 sjsir 文件构建一个 js 文件来实现一个插件系统,这样我的其余编译就无法在编译时完成。我曾经在 0.6.3 中使用以下代码实现相同的过程,但它似乎已被弃用。您推荐使用什么算法来实现与 0.6.13 相同的操作?
谢谢
val scalajsLib = copyJar("scalajs-library_2.11-0.6.3")
val semantics = org.scalajs.core.tools.sem.Semantics.Defaults
val partialClasspath =
PartialClasspathBuilder.build(collection.immutable.Seq(scalajsLib, src))
val completeClasspath = partialClasspath.resolve()
val optimizer = new ScalaJSOptimizer(semantics)
val logger = new ScalaConsoleLogger
val out = WritableFileVirtualJSFile(
new java.io.File(target, JS_FILE))
if (optimized) {
val sems = semantics.optimized
new ScalaJSClosureOptimizer(sems).optimizeCP(
new ScalaJSOptimizer(sems),
completeClasspath,
ScalaJSClosureOptimizer.Config(out),
logger
)
} else {
optimizer.optimizeCP(
completeClasspath,
ScalaJSOptimizer.Config(out, checkIR = false, wantSourceMap = !optimized),
logger
)
}
工具 API 确实在 0.6.5 中发生了巨大变化。它变得更加简单,并且在未来能够以不间断的方式发展。
你上面的代码可以用新的API写成如下:
import java.io.File
import org.scalajs.core.tools.io._
import org.scalajs.core.tools.sem._
import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind}
import org.scalajs.core.tools.linker.Linker
import org.scalajs.core.tools.logging.ScalaConsoleLogger
def link(inputClasspath: Seq[File], outputJSFile: File): Unit = {
// Obtain VirtualScalaJSIRFile's from the input classpath
val irCache = new IRFileCache().newCache
val irContainers = IRFileCache.IRContainer.fromClasspath(inputClasspath)
val sjsirFiles = irCache.cached(irContainers)
// A bunch of options. Here we use all the defaults
val semantics = Semantics.Defaults
val outputMode = OutputMode.Default
val moduleKind = ModuleKind.NoModule
val linkerConfig = Linker.Config()
// Actual linking
val linker = Linker(semantics, outputMode, moduleKind, linkerConfig)
val logger = new ScalaConsoleLogger
linker.link(sjsirFiles, WritableFileVirtualJSFile(outputJSFile), logger)
}
您可以使用以下参数调用该 link
函数,以与您上面的代码段完全匹配:
link(Seq(scalajsLib, src), new java.io.File(target, JS_FILE))
如果您打算在同一个进程中的同一个类路径上多次调用此方法,建议缓存并跨运行重用实例 irCache
和 linker
,因为这将大大加快进程。
有没有办法防止在 link 时间的 sjsir 批次(生成消息:XXX already seen
)中出现关于 class 重复的错误?我想是的,因为在编译时从 build.sbt.
完成构建时不会发生此错误
我需要在运行时从 sjsir 文件构建一个 js 文件来实现一个插件系统,这样我的其余编译就无法在编译时完成。我曾经在 0.6.3 中使用以下代码实现相同的过程,但它似乎已被弃用。您推荐使用什么算法来实现与 0.6.13 相同的操作? 谢谢
val scalajsLib = copyJar("scalajs-library_2.11-0.6.3")
val semantics = org.scalajs.core.tools.sem.Semantics.Defaults
val partialClasspath =
PartialClasspathBuilder.build(collection.immutable.Seq(scalajsLib, src))
val completeClasspath = partialClasspath.resolve()
val optimizer = new ScalaJSOptimizer(semantics)
val logger = new ScalaConsoleLogger
val out = WritableFileVirtualJSFile(
new java.io.File(target, JS_FILE))
if (optimized) {
val sems = semantics.optimized
new ScalaJSClosureOptimizer(sems).optimizeCP(
new ScalaJSOptimizer(sems),
completeClasspath,
ScalaJSClosureOptimizer.Config(out),
logger
)
} else {
optimizer.optimizeCP(
completeClasspath,
ScalaJSOptimizer.Config(out, checkIR = false, wantSourceMap = !optimized),
logger
)
}
工具 API 确实在 0.6.5 中发生了巨大变化。它变得更加简单,并且在未来能够以不间断的方式发展。
你上面的代码可以用新的API写成如下:
import java.io.File
import org.scalajs.core.tools.io._
import org.scalajs.core.tools.sem._
import org.scalajs.core.tools.linker.backend.{OutputMode, ModuleKind}
import org.scalajs.core.tools.linker.Linker
import org.scalajs.core.tools.logging.ScalaConsoleLogger
def link(inputClasspath: Seq[File], outputJSFile: File): Unit = {
// Obtain VirtualScalaJSIRFile's from the input classpath
val irCache = new IRFileCache().newCache
val irContainers = IRFileCache.IRContainer.fromClasspath(inputClasspath)
val sjsirFiles = irCache.cached(irContainers)
// A bunch of options. Here we use all the defaults
val semantics = Semantics.Defaults
val outputMode = OutputMode.Default
val moduleKind = ModuleKind.NoModule
val linkerConfig = Linker.Config()
// Actual linking
val linker = Linker(semantics, outputMode, moduleKind, linkerConfig)
val logger = new ScalaConsoleLogger
linker.link(sjsirFiles, WritableFileVirtualJSFile(outputJSFile), logger)
}
您可以使用以下参数调用该 link
函数,以与您上面的代码段完全匹配:
link(Seq(scalajsLib, src), new java.io.File(target, JS_FILE))
如果您打算在同一个进程中的同一个类路径上多次调用此方法,建议缓存并跨运行重用实例 irCache
和 linker
,因为这将大大加快进程。
有没有办法防止在 link 时间的 sjsir 批次(生成消息:XXX already seen
)中出现关于 class 重复的错误?我想是的,因为在编译时从 build.sbt.