Сборка JS из SJSIR `вручную`

Мне нужно собрать файл js из файлов sjsir во время выполнения, чтобы реализовать систему плагинов, так что это не может быть сделано во время компиляции с остальной частью моей компиляции. Я использовал для реализации того же процесса в 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
  )
}

2 ответа

Решение

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 через пробеги, поскольку это значительно ускорит процесс.

Смотрите также Scaladoc из API инструментов.

Есть ли способ предотвратить ошибки о повторении классов в пакете sjsir (который генерирует сообщение: XXX already seen) во время ссылки? Я предполагаю, что это так, поскольку эта ошибка не возникает, когда сборка выполняется во время компиляции из build.sbt.

Другие вопросы по тегам