6.2.2.3 搭建 Kotlin/JS 项目

原文链接: https://kotlinlang.org/docs/js-project-setup.html

6.2.2.3 搭建 Kotlin/JS 项目

Kotlin/JS 项目使用 Gradle 作为构建系统。为了让开发者轻松管理 Kotlin/JS 项目,我们提供了 kotlin.multiplatform Gradle 插件,它提供项目配置工具,以及用于自动化 JavaScript 开发常见例行工作的辅助任务。

该插件使用 npm 或 Yarn 包管理器在后台下载 npm 依赖,并使用 webpack 从 Kotlin 项目构建 JavaScript 包。依赖管理和配置调整大部分可以直接在 Gradle 构建文件中完成,同时也可以覆盖自动生成的配置以获得完全控制。

你可以在 build.gradle(.kts) 文件中手动把 org.jetbrains.kotlin.multiplatform 插件应用到 Gradle 项目:

Kotlin

1
2
3
plugins {
    kotlin("multiplatform") version "2.4.20"
}

Groovy

1
2
3
plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '2.4.20'
}

Kotlin Multiplatform Gradle 插件让你可以在构建脚本的 kotlin {} 块中管理项目的各个方面:

1
2
3
kotlin {
    // ...
}

在 kotlin {} 块中,你可以管理以下方面:

执行环境

Kotlin/JS 项目可以面向两种不同的执行环境:

  • 浏览器,用于浏览器中的客户端脚本
  • Node.js,用于在浏览器之外运行 JavaScript 代码,例如服务端脚本。

要为 Kotlin/JS 项目定义目标执行环境,请添加 js {} 块,并在其中放入 browser {} 或 nodejs {}:

1
2
3
4
5
6
7
kotlin {
    js {
        browser {
        }
        binaries.executable()
    }
}

binaries.executable() 这条指令显式要求 Kotlin 编译器生成可执行的 .js 文件。省略 binaries.executable() 会让编译器只生成 Kotlin 内部库文件,这些文件可被其他项目使用,但无法单独运行。

提示: 这通常比创建可执行文件更快,在处理项目的非叶子模块时可能是一种优化。

Kotlin Multiplatform 插件会自动为所选环境配置相应的任务。这包括下载并安装运行和测试应用所需的环境与依赖。这让开发者无需额外配置就能构建、运行和测试简单项目。也可以选择使用已有的安装。了解如何使用预装的 Node.js。

对 ES2015 特性的支持

Kotlin 提供对 ES2015 特性的支持,包括:

  • 模块,可简化代码库并提升可维护性。
  • 类,可引入面向对象原则,从而得到更清晰、更直观的代码。
  • 用于编译挂起函数的生成器,可改善最终包体积并有助于调试。
  • JavaScript 代码内联。

你可以在 build.gradle(.kts) 文件中添加 es2015 编译目标,一次性启用所有受支持的 ES2015 特性:

1
2
3
4
5
tasks.withType<KotlinJsCompile>().configureEach {
    compilerOptions {
        target = "es2015"
    }
}

在官方文档中进一步了解 ES2015(ECMAScript 2015、ES6)。

配置输出粒度

你可以选择编译器在项目中如何输出 .js 文件:

  • 每个模块一个文件。默认情况下,JS 编译器会为每个项目模块输出单独的 .js 文件作为编译结果。
  • 整个项目一个文件。你可以通过在 gradle.properties 文件中添加以下行,把整个项目编译为单个 .js 文件:
  kotlin.js.ir.output.granularity=whole-program // 'per-module' 是默认值
  • 每个文件一个。你可以设置更细粒度的输出,为每个 Kotlin 文件生成一个(如果该文件包含导出声明,则为两个)JavaScript 文件。要启用按文件编译模式:
  1. 把 es2015 设置为编译目标,以支持项目中的 ES2015 特性。
  2. 在 gradle.properties 文件中添加以下行:
     kotlin.js.ir.output.granularity=per-file // 'per-module' 是默认值

生成 TypeScript 声明文件(d.ts)

实验性

Kotlin/JS 编译器可以从你的 Kotlin 代码生成 TypeScript 定义。JavaScript 工具和 IDE 在处理混合应用时可以使用这些定义来:

  • 提供自动补全
  • 支持静态分析器
  • 简化在 JavaScript 和 TypeScript 项目中添加 Kotlin 代码的过程

生成 TypeScript 定义对业务逻辑共享用例尤其有价值。

编译器会收集所有带 @JsExport 标记的顶层声明,并自动在 .d.ts 文件中生成 TypeScript 定义。

要生成 TypeScript 定义,请在 Gradle 构建文件中显式配置。把 generateTypeScriptDefinitions() 函数添加到 build.gradle.kts 文件的 js {} 块中:

1
2
3
4
5
6
7
8
kotlin {
    js {
        binaries.executable()
        browser {
        }
        generateTypeScriptDefinitions()
    }
}

你可以在 build/js/packages/<package_name>/kotlin 目录中找到这些定义,它们与相应的未经过 webpack 处理的 JavaScript 代码放在一起。

依赖

要声明依赖,请在 build.gradle(.kts) 文件中 jsMain 源集的 dependencies {} 块里进行:

Kotlin

1
2
3
4
5
6
7
8
9
kotlin {
    sourceSets {
        jsMain {
            dependencies {
                implementation("org.example.myproject:1.1.0")
            }
        }
    }
}

Groovy

1
2
3
4
5
6
7
8
9
kotlin {
    sourceSets {
        jsMain {
            dependencies {
                implementation 'org.example.myproject:1.1.0'
            }
        }
    }
}

只有包含 Kotlin/JS 产物的库才能作为依赖使用。要解析依赖,请在 build.gradle(.kts) 文件的 repositories {} 块中声明 Gradle 应查找它们的仓库。例如:

1
2
3
repositories {
    mavenCentral()
}

如果你添加的库依赖来自 npm 的包,Gradle 也会自动解析这些传递依赖。

Kotlin 标准库

对标准库的依赖会自动添加。标准库的版本与 Kotlin Multiplatform 插件的版本相同。

对于多平台测试,可以使用 kotlin.test API。创建多平台项目时,你可以在 commonTest 中使用单个依赖为所有源集添加测试依赖:

Kotlin

1
2
3
4
5
6
7
kotlin {
    sourceSets {
        commonTest.dependencies {
            implementation(kotlin("test")) // 自动引入所有平台依赖
        }
    }
}

Groovy

1
2
3
4
5
6
7
8
9
kotlin {
    sourceSets {
        commonTest {
            dependencies {
                implementation kotlin("test") // 自动引入所有平台依赖
            }
        }
    }
}

npm 依赖

在 JavaScript 世界中,管理依赖最常见的方式是 npm。它提供了最大的 JavaScript 模块公共仓库。

Kotlin Multiplatform Gradle 插件让你可以像声明其他依赖一样在 Gradle 构建脚本中声明 npm 依赖。

要声明 npm 依赖,请把它的名称和版本传给依赖声明中的 npm() 函数。你也可以基于 npm 的 semver 语法指定一个或多个版本范围。

Kotlin

1
2
3
4
5
6
7
8
9
kotlin {
    sourceSets {
        jsMain {
            dependencies {
                implementation(npm("core-js", "^3.38.1"))
            }
        }
    }
}

Groovy

1
2
3
4
5
6
7
8
9
kotlin {
    sourceSets {
        jsMain {
            dependencies {
                implementation npm('core-js', '^3.38.1')
            }
        }
    }
}

默认情况下,该插件使用一个独立的 Yarn 包管理器实例来下载和安装 npm 依赖。它无需额外配置即可工作,但你可以按需调整它。

你也可以改用 npm 包管理器直接处理 npm 依赖。要使用 npm 作为包管理器,请在 gradle.properties 文件中设置以下属性:

kotlin.js.yarn=false

除常规依赖之外,还可以从 Gradle DSL 使用另外三种依赖类型。要了解每种依赖类型最合适的使用场景,请查看 npm 链接的官方文档:

npm 依赖安装完成后,你就可以按照从 Kotlin 调用 JS中所述在代码中使用它的 API。

run 任务

Kotlin Multiplatform Gradle 插件提供了一个 jsBrowserDevelopmentRun 任务,让你无需额外配置就能运行纯 Kotlin/JS 项目。

要在浏览器中运行 Kotlin/JS 项目,该任务是 browserDevelopmentRun 任务的别名(后者在 Kotlin 多平台项目中也可用)。它使用 webpack-dev-server 来提供你的 JavaScript 产物。如果你想要自定义 webpack-dev-server 使用的配置(例如调整服务器运行的端口),请使用 webpack 配置文件。

要运行面向 Node.js 的 Kotlin/JS 项目,请使用 jsNodeDevelopmentRun 任务,它是 nodeRun 任务的别名。

要运行项目,请执行标准的生命周期任务 jsBrowserDevelopmentRun,或与之对应的别名:

1
./gradlew jsBrowserDevelopmentRun

要在修改源文件后自动触发应用重新构建,请使用 Gradle 的持续构建特性:

1
./gradlew jsBrowserDevelopmentRun --continuous

或者

1
./gradlew jsBrowserDevelopmentRun -t

项目构建成功后,webpack-dev-server 会自动刷新浏览器页面。

test 任务

Kotlin Multiplatform Gradle 插件会自动为项目搭建测试基础设施。它会下载并安装所需的测试运行器和其他依赖。

对于浏览器项目,你可以在 Karma 测试运行器和新的浏览器测试 DSL 之间选择。对于 Node.js 项目,可以使用 Mocha 测试框架。

该插件还提供实用的测试特性,例如:

  • Source map 生成
  • 测试报告生成
  • 在控制台中显示测试运行结果

Karma

警告: Karma 项目已被弃用。预计不会有新特性或缺陷修复。作为浏览器测试的替代方案,请试用新的浏览器测试 DSL。

要配置 Karma 测试运行器,请在 build.gradle(.kts) 文件中浏览器目标的 testTask 内添加 useKarma {} 块。例如,要针对特定浏览器运行测试,请使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
kotlin {
    js {
        browser {
            testTask {
                useKarma {
                    useIe()
                    useSafari()
                    useFirefox()
                    useChrome()
                    useChromeCanary()
                    useChromeHeadless()
                    usePhantomJS()
                    useOpera()
                }
            }
        }
        binaries.executable()
        // ...
    }
}

或者,你也可以在 gradle.properties 文件中添加浏览器测试目标:

1
kotlin.js.browser.karma.browsers=firefox,safari

这让你可以为所有模块定义浏览器列表,然后在特定模块的构建文件中添加特定浏览器。

Kotlin Multiplatform Gradle 插件会在构建时自动在 build/js/packages/projectName-test/karma.conf.js 生成 Karma 配置文件。该文件包含你在构建文件 useKarma {} 块中设置的配置。

你也可以把额外的配置文件放在项目根目录的 karma.config.d 目录中。构建时,该目录下所有 .js 配置文件都会被收集并自动合并到生成的 karma.conf.js 中。

关于 Karma 配置的更多信息,请参阅 Karma 文档。

用于浏览器测试的 DSL

实验性

Kotlin 提供了一个实验性 DSL,用于在浏览器环境中运行 Kotlin/JS 测试。它被设计为与技术无关。当前实现在底层包含以下工具:

  • Playwright 充当浏览器驱动和分发管理器,支持 Chromium、Firefox 和 WebKit(Safari)浏览器引擎。
  • Mocha 充当测试运行器。
  • webpack 充当打包器(将在未来的版本中被 Vite 取代)。

要试用新的浏览器测试 DSL,请在你的 Kotlin/JS 目标的 browser {} 内添加需要选择启用的 test {} 块:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import org.jetbrains.kotlin.gradle.ExperimentalJsTestDsl
import kotlin.time.Duration.Companion.seconds

kotlin {
    js {
        browser {
            @OptIn(ExperimentalJsTestDsl::class)
            test {
                // 使用 kotlin.Duration 配置所有运行器的默认超时时间
                timeout = 30.seconds
                // 使用 Gradle provider 配置无头模式
                headless = providers
                    .environmentVariable("IS_IN_CI")
                    .map { it.toBoolean() }
                    .orElse(false)
                // 启用并配置自定义 Chromium 运行器
                chromium("chromium-no-webgl2") {
                    // 覆盖该运行器的默认超时时间
                    timeout = 10.seconds

                    // Chromium 特有的额外启动参数
                    launchArgs.add("--disable-webgl2")
                }
                // 启用 Firefox 运行器
                firefox()
                // 启用 WebKit(Safari)测试运行器
                webkit()
                // 启用并配置自定义 WebKit 运行器
                webkit("headful") {
                    headless = false
                }
            }
        }
    }
}

关于新浏览器测试 DSL 配置的更多信息,请参阅在 Kotlin/JS 中运行测试。

Node.js

对于 Node.js 项目,Kotlin Multiplatform Gradle 插件会自动搭建 Mocha 测试框架。

要指定 Node.js 测试运行器使用的环境变量(例如向测试传递外部信息,或微调包解析),请在构建文件的 testTask {} 块中使用带键值对的 environment() 函数:

1
2
3
4
5
6
7
8
9
kotlin {
    js {
        nodejs {
            testTask {
                environment("key", "value")
            }
        }
    }
}

运行测试

默认情况下,Kotlin Multiplatform Gradle 插件使用 Headless Chrome 来运行浏览器测试。插件不捆绑任何浏览器;测试运行器对缺失浏览器的处理方式不同:

  • 使用 Karma 时,你的机器上应已安装其他浏览器,以便插件用它运行测试。如果你在持续集成服务器上执行 Kotlin/JS 测试,请确保那里也安装了你想测试的浏览器。
  • 使用新的浏览器测试 DSL 时,插件会在首次运行时通过 playwright install 命令安装必要的浏览器。Playwright 管理这些浏览器的位置,不使用本地已安装的浏览器。

要运行测试,请执行标准的生命周期任务 check:

1
./gradlew check

如果你想跳过测试,请在构建文件的 testTask {} 块中禁用它们:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kotlin {
    js {
        browser {
            testTask {
                enabled.set(false)
            }
        }
        binaries.executable()
        // ...
    }
}

webpack 打包

对于浏览器目标,Kotlin Multiplatform Gradle 插件使用广为人知的 webpack 模块打包器。

webpack 任务

最常见的 webpack 调整可以通过 Gradle 构建文件中的 kotlin.js.browser.webpackTask {} 配置块直接完成:

  • mainOutputFileName —— webpack 输出文件的名称。它会在 webpack 任务执行后生成到 <projectDir>/build/kotlin-webpack/<targetName>/<binaryName>。默认值是项目名。
  • output.libraryTarget —— webpack 输出的模块系统。进一步了解 Kotlin/JS 项目可用的模块系统。默认值是 umd。
1
2
3
4
webpackTask {
    mainOutputFileName = "mycustomfilename.js"
    output.libraryTarget = "commonjs2"
}

你也可以在 commonWebpackConfig {} 块中配置用于打包、运行和测试任务的通用 webpack 设置。

webpack 配置文件

Kotlin Multiplatform Gradle 插件会在构建时自动生成标准的 webpack 配置文件。它位于 build/js/packages/projectName/webpack.config.js。

如果你想对 webpack 配置做进一步调整,请把额外的配置文件放在项目根目录下一个名为 webpack.config.d 的目录中。构建项目时,所有 .js 配置文件都会自动合并到 build/js/packages/projectName/webpack.config.js 中。例如,要添加新的 webpack loader,请在 webpack.config.d 目录中的某个 .js 文件里添加以下内容:

注意: 在这种情况下,配置对象是全局对象 config。你需要在脚本中修改它。

1
2
3
4
config.module.rules.push({
    test: /\.extension$/,
    loader: 'loader-name'
});

所有 webpack 配置能力在其文档中都有很好的描述。

构建可执行文件

为了通过 webpack 构建可执行的 JavaScript 产物,Kotlin Multiplatform Gradle 插件包含 jsBrowserDevelopmentWebpack 和 jsBrowserProductionWebpack 这两个 Gradle 任务。

  • jsBrowserDevelopmentWebpack 创建开发产物,它们体积更大但创建耗时更少。因此,在积极开发期间请使用 jsBrowserDevelopmentWebpack 任务。
  • jsBrowserProductionWebpack 会对生成的产物应用无用代码消除,并压缩得到的 JavaScript 文件,耗时更长但生成的可执行文件更小。因此,在准备把项目用于生产时请使用 jsBrowserProductionWebpack 任务。

执行其中任一任务即可获得用于开发或生产的相应产物。除非另有指定,生成的文件会位于 build/kotlin-webpack。

1
./gradlew jsBrowserProductionWebpack

请注意,只有当你的目标被配置为生成可执行文件(通过 binaries.executable())时,这些任务才可用。

要在 build/dist/<targetName>/<binaryName> 目录中生成分发产物,请改为运行 jsBrowserDistribution 任务:

1
./gradlew jsBrowserDistribution

该任务会生成包含项目资源的、可直接使用的分发产物。

CSS

Kotlin Multiplatform Gradle 插件还支持 webpack 的 CSS 和 style loader。虽然所有选项都可以通过直接修改用于构建项目的 webpack 配置文件来更改,但最常用的设置可以直接在 build.gradle(.kts) 文件中配置。

要在项目中启用 CSS 支持,请在 Gradle 构建文件的 commonWebpackConfig {} 块中设置 cssSupport.enabled 选项。使用向导创建新项目时,该配置也默认启用。

Kotlin

1
2
3
4
5
6
7
browser {
    commonWebpackConfig {
        cssSupport {
            enabled.set(true)
        }
    }
}

Groovy

1
2
3
4
5
6
7
browser {
    commonWebpackConfig {
        cssSupport {
            it.enabled = true
        }
    }
}

或者,你也可以分别为 webpackTask {}、runTask {} 和 testTask {} 添加 CSS 支持:

Kotlin

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
browser {
    webpackTask {
        cssSupport {
            enabled.set(true)
        }
    }
    runTask {
        cssSupport {
            enabled.set(true)
        }
    }
    testTask {
        useKarma {
            // ...
            webpackConfig.cssSupport {
                enabled.set(true)
            }
        }
    }
}

Groovy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
browser {
    webpackTask {
        cssSupport {
            it.enabled = true
        }
    }
    runTask {
        cssSupport {
            it.enabled = true
        }
    }
    testTask {
        useKarma {
            // ...
            webpackConfig.cssSupport {
                it.enabled = true
            }
        }
    }
}

在项目中启用 CSS 支持有助于避免未配置项目尝试使用样式表时出现的常见错误,例如 Module parse failed: Unexpected character '@' (14:0)。

你可以使用 cssSupport.mode 指定应如何处理遇到的 CSS。可用的值有:

  • "inline"(默认):样式会被添加到全局 <style> 标签中。
  • "extract":样式会被提取到单独的文件中。之后可以从 HTML 页面引入它们。
  • "import":样式会作为字符串处理。如果你需要从代码中访问 CSS(例如 val styles = require("main.css")),这会很有用。

要在同一个项目中使用不同的模式,请使用 cssSupport.rules。在这里你可以指定 KotlinWebpackCssRules 列表,每一项都定义一种模式以及 include 和 exclude 模式。

Node.js

对于面向 Node.js 的 Kotlin/JS 项目,该插件会自动在宿主机上下载并安装 Node.js 环境。如果你已有 Node.js 实例,也可以使用它。

你可以为每个子项目配置 Node.js 设置,也可以为整个项目统一设置。

修改 Node.js 版本

默认的 Node.js 版本目前是 24.16.0,但你可以为特定子项目使用不同的版本。请把以下几行添加到子项目的 build.gradle(.kts) 文件中。例如:

Kotlin

1
2
3
project.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin> {
    project.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec>().version = "26.2.0"
}

Groovy

1
2
3
project.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin) {
    project.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec).version = "26.2.0"
}

要为整个项目(包括所有子项目)设置版本,请把相同的代码应用到 allprojects {} 块。例如:

Kotlin

1
2
3
4
5
allprojects {
    project.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin> {
        project.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec>().version = "26.2.0"
    }
}

Groovy

1
2
3
4
5
allprojects {
    project.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin) {
        project.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec).version = "26.2.0"
    }
}

使用预装的 Node.js

如果构建 Kotlin/JS 项目的宿主机上已安装 Node.js,你可以配置 Kotlin Multiplatform Gradle 插件使用它,而不是安装自己的 Node.js 实例。

要使用预装的 Node.js 实例,请把以下几行添加到 build.gradle(.kts) 文件中:

Kotlin

1
2
3
4
project.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin> {
    // 默认行为则设为 `true`
    project.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec>().download = false
}

Groovy

1
2
3
4
project.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin) {
    // 默认行为则设为 `true`
    project.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec).download = false
}

Yarn

默认情况下,为了在构建时下载并安装你声明的依赖,该插件管理自己的 Yarn 包管理器实例。它无需额外配置即可工作,但你可以调整它,或使用宿主机上已安装的 Yarn。

额外的 Yarn 特性:.yarnrc

要配置额外的 Yarn 特性,请在项目根目录放置一个 .yarnrc 文件。构建时它会被自动读取。

例如,要为 npm 包使用自定义仓库,请在项目根目录名为 .yarnrc 的文件中添加以下行:

1
registry "http://my.registry/api/npm/"

要进一步了解 .yarnrc,请访问官方 Yarn 文档。

使用预装的 Yarn

如果构建 Kotlin/JS 项目的宿主机上已安装 Yarn,你可以配置 Kotlin Multiplatform Gradle 插件使用它,而不是安装自己的 Yarn 实例。

要使用预装的 Yarn 实例,请把以下几行添加到 build.gradle(.kts):

Kotlin

1
2
3
4
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
    rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootEnvSpec>().download = false
    // 默认行为则为 "true"
}

Groovy

1
2
3
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin) {
    rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootEnvSpec).download = false
}

通过 kotlin-js-store 进行版本锁定

项目根目录中的 kotlin-js-store 目录由 Kotlin Multiplatform Gradle 插件自动生成,用于存放版本锁定所需的 yarn.lock 文件。该锁文件完全由 Yarn 插件管理,并会在 kotlinNpmInstall Gradle 任务执行期间更新。

按照推荐做法,请把 kotlin-js-store 及其内容提交到你的版本控制系统。这能确保你的应用在所有机器上都使用完全相同的依赖树构建。

如有需要,你可以在 build.gradle(.kts) 中同时修改目录名和锁文件名:

Kotlin

1
2
3
4
5
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
    rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().lockFileDirectory =
        project.rootDir.resolve("my-kotlin-js-store")
    rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().lockFileName = "my-yarn.lock"
}

Groovy

1
2
3
4
5
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin) {
    rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension).lockFileDirectory =
        file("my-kotlin-js-store")
    rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension).lockFileName = 'my-yarn.lock'
}

警告: 修改锁文件名可能导致依赖检查工具不再读取该文件。

要进一步了解 yarn.lock,请访问官方 Yarn 文档。

报告 yarn.lock 已更新

Kotlin/JS 提供了一些 Gradle 设置,可以在 yarn.lock 文件被更新时通知你。当你想在 CI 构建过程中 yarn.lock 被静默更改时得到通知,可以使用这些设置:

  • YarnLockMismatchReport,指定如何报告 yarn.lock 文件的更改。你可以使用以下值之一:
  • FAIL 让相应的 Gradle 任务失败。这是默认值。
  • WARNING 把更改信息写入警告日志。
  • NONE 禁用报告。
  • reportNewYarnLock,显式报告最近创建的 yarn.lock 文件。默认情况下该选项是禁用的:在首次启动时生成新的 yarn.lock 文件是常见做法。你可以用该选项确保该文件已被提交到仓库。
  • yarnLockAutoReplace,在每次运行 Gradle 任务时自动替换 yarn.lock。

要使用这些选项,请按如下方式更新 build.gradle(.kts):

Kotlin

1
2
3
4
5
6
7
8
9
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension

rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
    rootProject.the<YarnRootExtension>().yarnLockMismatchReport =
        YarnLockMismatchReport.WARNING // NONE | FAIL
    rootProject.the<YarnRootExtension>().reportNewYarnLock = false // true
    rootProject.the<YarnRootExtension>().yarnLockAutoReplace = false // true
}

Groovy

1
2
3
4
5
6
7
8
9
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension

rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin) {
    rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension).yarnLockMismatchReport =
        YarnLockMismatchReport.WARNING // NONE | FAIL
    rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension).reportNewYarnLock = false // true
    rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension).yarnLockAutoReplace = false // true
}

默认使用 –ignore-scripts 安装 npm 依赖

为降低执行来自被入侵的 npm 包中恶意代码的可能性,Kotlin Multiplatform Gradle 插件默认会在安装 npm 依赖时阻止执行生命周期脚本。

你可以通过在 build.gradle(.kts) 中添加以下几行来显式启用生命周期脚本的执行:

Kotlin

1
2
3
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
    rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().ignoreScripts = false
}

Groovy

1
2
3
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin) {
    rootProject.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension).ignoreScripts = false
}

分发目标目录

默认情况下,Kotlin/JS 项目构建结果位于项目根目录下的 /build/dist/<targetName>/<binaryName> 目录中。

要设置项目分发文件的另一个位置,请在构建脚本的 browser {} 块中添加 distribution {} 块,并使用 set() 方法为 outputDirectory 属性赋值。一旦你运行项目构建任务,Gradle 会把输出包和项目资源一起保存到该位置。

Kotlin

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kotlin {
    js {
        browser {
            distribution {
                outputDirectory.set(projectDir.resolve("output"))
            }
        }
        binaries.executable()
        // ...
    }
}

Groovy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kotlin {
    js {
        browser {
            distribution {
                outputDirectory = file("$projectDir/output")
            }
        }
        binaries.executable()
        // ...
    }
}

模块名

要调整 JavaScript 模块(生成在 build/js/packages/myModuleName 中)的名称,包括相应的 .js 和 .d.ts 文件,请使用 outputModuleName 选项:

1
2
3
4
5
kotlin {
    js {
        outputModuleName = "myModuleName"
    }
}

请注意,这不会影响 build/dist 中经过 webpack 处理的输出。

自定义 package.json

package.json 文件保存 JavaScript 包的元数据。npm 等流行的包注册中心要求所有发布的包都有这样的文件。它们用它来跟踪和管理包的发布。

Kotlin Multiplatform Gradle 插件会在构建时为 Kotlin/JS 项目自动生成 package.json。默认情况下,该文件包含必要数据:名称、版本、许可证、依赖以及一些其他包属性。

除基本包属性之外,package.json 还可以定义 JavaScript 项目的行为,例如标识可运行的脚本。

你可以通过 Gradle DSL 向项目的 package.json 添加自定义条目。要添加自定义字段,请在编译的 packageJson 块中使用 customField() 函数:

1
2
3
4
5
6
7
kotlin {
    js {
        compilations["main"].packageJson {
            customField("hello", mapOf("one" to 1, "two" to 2))
        }
    }
}

构建项目时,这段代码会把以下块添加到 package.json 文件中:

1
2
3
4
"hello": {
    "one": 1,
    "two": 2
}

在 npm 文档中进一步了解如何为 npm 注册中心编写 package.json 文件。