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

如何基于Kotlin/MP的commonMain构建Web Worker专用JS库?

问题:Kotlin多平台项目中Web Worker按需引入commonMain类避免代码重复

我有一个Kotlin多平台项目,支持Java后端和Angular前端,commonMain里的代码能同时构建给两个目标,已经在两边正常运行,项目还依赖一个叫melange的Kotlin/MP子模块库。

现在我要给Angular应用加Web Worker线程,已经创建了my.worker.ts模板文件并成功启动。我知道Worker里没法访问主应用加载的所有库代码,但需要从commonMain引入几个类。不过按主应用的方式导入会导致库代码完全重复(大概400KiB)。

想请教怎么只包含Web Worker需要的类,而不是完整的common构建产物?我想到两个方向:1. 在Gradle里创建单独的库构建目标,只包含必要类;2. 对生成的.js文件做死代码消除,移除未使用的内容,但不知道具体怎么实现。


解决方案

思路1:创建Gradle单独构建目标

  • 在Kotlin多平台模块的build.gradle.kts里新增一个专门的JS目标,命名为workerJs,配置它只关联Web Worker需要的代码和依赖:
kotlin {
    js(IR) {
        browser()
        binaries.executable()
    }
    // 新增Web Worker专用JS目标
    js(IR) {
        name = "workerJs"
        binaries.executable()
        // 指定输出目录,方便Angular后续引用
        compilations.main.outputDirectory.set(project.layout.buildDirectory.dir("js/worker"))
    }
    sourceSets {
        val workerMain by creating {
            dependsOn(commonMain)
            // 存放Worker专属代码的目录,把需要的类移到这里或者只引入指定包
            kotlin.srcDir("src/workerMain/kotlin")
            // 按需引入melange库,排除不需要的子模块
            dependencies {
                implementation(project(":melange")) {
                    exclude(module = "melange-unused-module")
                }
            }
        }
        // 把workerJs目标和workerMain源码集关联起来
        getByName("workerJsMain").dependsOn(workerMain)
    }
}
  • 把Web Worker需要的类从commonMain拆分到src/workerMain/kotlin目录,或者用expect/actual语法区分主应用和Worker的代码逻辑,确保workerMain只包含必要代码。
  • 构建完成后,在Angular的Web Worker文件里通过importScripts引用这个专用构建产物:
// my.worker.ts
importScripts('../path/to/workerJs/build/output.js');
// 直接使用需要的类即可

思路2:通过死代码消除(Tree Shaking)优化

  • 先确认Kotlin JS用的是IR编译器(目前默认就是),旧编译器对Tree Shaking支持很差。在build.gradle.kts里确认配置:
kotlin {
    js(IR) {
        browser {
            commonWebpackConfig {
                optimize = true // 开启Webpack优化,包含Tree Shaking
            }
        }
        binaries.executable()
    }
}
  • 在Web Worker里精准导入需要的类,不要导入整个common包:
// my.worker.ts
// 不要全量导入
// import * as common from '../path/to/common/build/output.js';
// 精准导入所需类
import { MyNeededClass, MyAnotherNeededClass } from '../path/to/common/build/output.js';
  • 确保依赖的melange库支持Tree Shaking:如果是自己的子模块,在它的build.gradle.kts里配置输出ES模块:
kotlin {
    js(IR) {
        binaries.library()
        compilations.main.output.jsTarget.dir = "esm" // 输出ES模块格式
    }
}
  • 最后开启Angular生产构建的优化,Angular会配合Webpack自动完成Tree Shaking:
// angular.json
{
  "projects": {
    "your-app": {
      "architect": {
        "build": {
          "configurations": {
            "production": {
              "optimization": true,
              "buildOptimizer": true,
              "vendorChunk": false
            }
          }
        }
      }
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:40:32