如何实现SBT任务在本地开发与发布时的差异化编译配置?
Scala.js自动化切换Closure编译器配置方案
针对你手动切换Closure编译器(GCC)配置的痛点,这里提供两种规范的自动化实现方式:
方案一:利用sbt多配置区分开发/发布环境
通过自定义Release配置,让开发环境默认关闭GCC,发布时使用启用GCC的配置,无需手动修改代码:
// 定义用于发布的Release配置,继承Compile的基础设置 lazy val Release = config("release").extend(Compile) // 定义JS模块通用配置 lazy val jsModuleSettings = Seq( // 开发环境:fullOptJS启用优化但关闭GCC Compile / fullLinkJS / scalaJSLinkerConfig ~= { _.withOptimizer(true).withClosureCompiler(false) }, // Release配置:启用优化和GCC,用于发布 Release / fullLinkJS / scalaJSLinkerConfig ~= { _.withOptimizer(true).withClosureCompiler(true) }, // 让Release配置的fullOptJS使用自身的linker配置 Release / fullOptJS := (Release / fullLinkJS).value ) // 应用配置到frontend和worker模块 lazy val frontend = project.in(file("frontend")) .settings(jsModuleSettings) .enablePlugins(ScalaJSPlugin) lazy val worker = project.in(file("worker")) .settings(jsModuleSettings) .enablePlugins(ScalaJSPlugin) // Backend模块发布时,使用Release配置下的JS产物 lazy val backend = project.in(file("backend")).settings( Compile / resourceGenerators += Def.task { Seq( (frontend / Release / fullOptJS).value.data, (worker / Release / fullOptJS).value.data ) }.taskValue )
使用方式:
- 本地开发测试:直接执行
frontend/fullOptJS或worker/fullOptJS,自动关闭GCC - 发布时:执行
backend/compile(会触发Release配置的JS构建),或直接执行frontend/release:fullOptJS生成带GCC优化的产物
方案二:自定义本地专用任务fullOptJSLocal
如果需要更明确的任务区分,可以直接创建一个本地专用的任务,独立于默认的fullOptJS:
// 定义本地专用任务:带优化但关闭GCC lazy val fullOptJSLocal = taskKey[Attributed[File]]("生成带优化但无Closure Compiler的JS文件,用于本地测试") lazy val jsModuleSettings = Seq( fullOptJSLocal := { // 获取基础配置并修改为关闭GCC val linkerConfig = (Compile / scalaJSLinkerConfig).value .withOptimizer(true) .withClosureCompiler(false) // 获取linker工具、IR文件和输出目录 val linker = (Compile / scalaJSLinker).value val irFiles = (Compile / scalaJSIR).value val outputDir = (Compile / crossTarget).value / "fullOptJS-local" val outputFile = outputDir / s"${name.value}-opt.js" // 执行链接操作生成JS文件 linker.link(irFiles, linkerConfig, outputFile, streams.value.log) // 返回与fullOptJS格式一致的带属性文件 Attributed.blank(outputFile) }, // 默认fullOptJS保持启用GCC,用于发布 Compile / fullLinkJS / scalaJSLinkerConfig ~= { _.withOptimizer(true).withClosureCompiler(true) } ) // 应用配置到模块 lazy val frontend = project.in(file("frontend")) .settings(jsModuleSettings) .enablePlugins(ScalaJSPlugin) lazy val worker = project.in(file("worker")) .settings(jsModuleSettings) .enablePlugins(ScalaJSPlugin) // Backend发布时仍使用默认的fullOptJS lazy val backend = project.in(file("backend")).settings( Compile / resourceGenerators += Def.task { Seq( (frontend / Compile / fullOptJS).value.data, (worker / Compile / fullOptJS).value.data ) }.taskValue )
使用方式:
- 本地测试:执行
frontend/fullOptJSLocal或worker/fullOptJSLocal - 发布:直接执行
backend/compile或默认的frontend/fullOptJS
内容的提问来源于stack exchange,提问作者Suma
相关产品推荐
相关产品推荐

