You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从多个Scala.js项目创建前端并适配跨构建配置

实现方案

方案一(最低成本):无需拆分项目,直接创建多独立Websocket连接

http4s-dom提供的connectHighLevel没有全局单例限制,完全没必要为了拆分WS连接新建独立Scala.js项目。你可以直接在现有前端代码里,给聊天、游戏大厅、核心游戏逻辑分别调用一次connectHighLevel创建独立连接实例,每个实例单独绑定消息处理器、重连规则、生命周期钩子即可,互相完全不干扰,零构建改造成本。

方案二(适合代码解耦需求):拆分独立前端模块

如果要按业务域拆分独立前端模块,按下面的配置调整即可:

1. 调整sbt跨构建配置,复用共享代码

Scala.js跨构建原生支持多JS模块依赖公共共享层,直接修改build.sbt:

// 原有跨构建项目保留,所有JVM/JS共享的代码、公共模型、工具逻辑都放在这里
lazy val diceGame = crossProject(JSPlatform, JVMPlatform)
  .in(file("."))
  // 保留你原有的所有依赖、编译配置
  .jvmSettings(/* 服务端原有配置不动 */)
  .jsSettings(/* 核心前端公共配置不动 */)

// 新增聊天业务JS模块
lazy val chatJS = project.in(file("modules/chat-js"))
  .enablePlugins(ScalaJSPlugin)
  .dependsOn(diceGame.js) // 直接依赖原有跨构建的JS侧,所有公共代码直接复用
  .settings(
    // 聊天模块单独的依赖、配置,比如WS相关的自定义逻辑
  )

// 新增游戏大厅业务JS模块
lazy val lobbyJS = project.in(file("modules/lobby-js"))
  .enablePlugins(ScalaJSPlugin)
  .dependsOn(diceGame.js) // 同样复用公共共享代码
  .settings(
    // 大厅模块单独的配置
  )

// 根项目聚合所有模块,编译的时候会一次性处理所有子模块
lazy val root = project.in(file("."))
  .aggregate(diceGame.jvm, diceGame.js, chatJS, lobbyJS)

配置完成后,原有共享层的所有代码都可以在chatJS、lobbyJS里直接引用,不需要重复编写。

2. 单JS文件引入的实现

不要手动合并编译输出的JS文件,Scala.js编译产物有严格的初始化顺序,手动拼接很容易出现类找不到、初始化时序错误。推荐用单入口聚合的方案:

  • 把原有diceGame.js作为前端唯一入口,让它依赖chatJS、lobbyJS两个业务模块:
lazy val diceGameJS = diceGame.js
  .dependsOn(chatJS, lobbyJS)
  .settings(
    // 主入口的启动逻辑里,分别调用聊天模块、大厅模块的WS初始化方法即可
  )

sbt编译的时候会自动把所有依赖模块的代码打包到diceGame.js的输出产物里,HTML里只需要引入这一个JS文件就行,不需要额外处理合并逻辑。

  • 如果后续要做代码分割按需加载,再考虑用Scala.js的模块拆分配置配合ES module加载即可,初期单入口打包是成本最低、最稳定的方案。

内容的提问来源于stack exchange,提问作者Onajk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:06:26