Build JS from SJSIR `manually`

人走茶凉 提交于 2019-12-08 02:03:35

问题


I need to build a js file from sjsir files at runtime to implement a system of plugins, so that it can't be done at compile time with the rest of my compilation. I used to implement the same process in 0.6.3 with the following code, but it seems to be deprecated. What algorithm do you recommand to achieve the same action with 0.6.13 ? Thanks

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
  )
}

回答1:


The Tools API has dramatically changed in 0.6.5, indeed. It became much simpler and more able to evolve in non-breaking ways in the future.

Your code above can be written with the new API as follows:

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)
}

And you can call that link function with the following arguments, to exactly match your above snippet:

link(Seq(scalajsLib, src), new java.io.File(target, JS_FILE))

If you intend to call this method several times on the same classpath within the same process, it is advised to cache and reuse the instances irCache and linker across runs, as this will considerably speed up the process.

See also the Scaladoc of the Tools API.




回答2:


Is there a way to prevent from errors about class repetition in the batch of sjsir (which generates the message: XXX already seen) at link time ? I guess it is, since this error does not occur when the build is done at compile time from the build.sbt.



来源:https://stackoverflow.com/questions/40860950/build-js-from-sjsir-manually

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!