Kotlin/JS 프로젝트 설정하기
Kotlin/JS 프로젝트 설정하기
Kotlin/JS 프로젝트는 빌드 시스템으로 Gradle을 사용해요. 개발자가 Kotlin/JS 프로젝트를 쉽게 관리할 수 있도록, 우리는 JavaScript 개발에 전형적인 루틴을 자동화하는 헬퍼 태스크와 함께 프로젝트 구성 도구를 제공하는 kotlin.multiplatform Gradle 플러그인을 제공해요.
이 플러그인은 배경에서 npm 또는 Yarn 패키지 매니저를 사용해 npm 의존성을 다운로드하고, webpack을 사용해 Kotlin 프로젝트에서 JavaScript 번들을 만듭니다. 의존성 관리와 구성 조정은 대부분 Gradle 빌드 파일에서 직접 할 수 있으며, 완전한 제어를 위해 자동 생성된 구성을 override할 수 있는 옵션도 있어요.
build.gradle(.kts) 파일에서 수동으로 org.jetbrains.kotlin.multiplatform 플러그인을 Gradle 프로젝트에 적용할 수 있어요.
plugins {
kotlin("multiplatform") version "2.4.20"
}
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '2.4.20'
}
Kotlin Multiplatform Gradle 플러그인을 사용하면 빌드 스크립트의 kotlin {} 블록에서 프로젝트의 다양한 측면을 관리할 수 있어요.
kotlin {
// ...
}
kotlin {} 블록 안에서 다음 측면들을 관리할 수 있어요.
- 타깃 실행 환경: browser 또는 Node.js
- ES2015 기능 지원: classes, modules, generators
- 출력 세분화(granularity) 구성
- TypeScript 선언 파일 생성
- 프로젝트 의존성: Maven 및 npm
- 실행 구성
- 테스트 구성
- 브라우저 프로젝트를 위한 번들링과 CSS 지원
- 타깃 디렉터리와 모듈 이름
- 프로젝트의
package.json파일
실행 환경
Kotlin/JS 프로젝트는 두 가지 다른 실행 환경을 타깃으로 할 수 있어요.
- Browser — 브라우저에서의 클라이언트 사이드 스크립팅용
- Node.js — 브라우저 밖에서 JavaScript 코드를 실행하기 위한 것으로, 예를 들어 서버 사이드 스크립팅용이에요.
Kotlin/JS 프로젝트의 타깃 실행 환경을 정의하려면 안에 browser {} 또는 nodejs {}를 넣은 js {} 블록을 추가해요.
kotlin {
js {
browser {
}
binaries.executable()
}
}
binaries.executable() 지시어는 Kotlin 컴파일러가 실행 가능한 .js 파일을 명시적으로 생성하도록 해요. binaries.executable()을 생략하면 컴파일러가 Kotlin 내부 라이브러리 파일만 생성하는데, 이 파일들은 다른 프로젝트에서 사용할 수 있지만 단독으로는 실행할 수 없어요.
보통 실행 파일을 만드는 것보다 빠르며, 프로젝트의 비단말(non-leaf) 모듈을 다룰 때 유용한 최적화가 될 수 있어요.
Kotlin Multiplatform 플러그인은 선택한 환경에서 작업하도록 태스크를 자동으로 구성해요. 여기에는 애플리케이션을 실행하고 테스트하는 데 필요한 환경과 의존성의 다운로드 및 설치가 포함돼요. 덕분에 개발자는 추가 구성 없이도 간단한 프로젝트를 빌드, 실행, 테스트할 수 있어요. 기존 설치본을 사용하는 옵션도 있어요. 사전 설치된 Node.js 사용 방법을 알아보세요.
ES2015 기능 지원
Kotlin은 다음을 포함한 ES2015 기능을 지원해요.
- 코드베이스를 단순화하고 유지 관리를 개선하는 Modules
- OOP 원칙을 통합해 더 깔끔하고 직관적인 코드를 만드는 Classes
- suspend functions 컴파일을 위한 Generators — 최종 번들 크기를 개선하고 디버깅을 돕습니다.
- JavaScript 코드 인라인
build.gradle(.kts) 파일에 es2015 컴파일 타깃을 추가하면 지원되는 모든 ES2015 기능을 한 번에 활성화할 수 있어요.
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' is the default
- 파일당 하나. Kotlin 파일마다 JavaScript 파일 하나(파일에 export 선언이 있으면 두 개)를 생성하는 더 세분화된 출력을 설정할 수 있어요. 파일별 컴파일 모드를 활성화하려면:
- 프로젝트에서 ES2015 기능을 지원하도록
es2015를 컴파일 타깃으로 설정해요. gradle.properties파일에 다음 줄을 추가해요.
- 프로젝트에서 ES2015 기능을 지원하도록
kotlin.js.ir.output.granularity=per-file // 'per-module' is the default
TypeScript 선언 파일(d.ts) 생성
Kotlin/JS 컴파일러는 Kotlin 코드에서 TypeScript 정의를 생성할 수 있어요. 이 정의는 하이브리드 애플리케이션 작업 시 JavaScript 도구와 IDE가 다음을 위해 사용할 수 있어요.
- 자동 완성 제공
- 정적 분석기 지원
- JavaScript·TypeScript 프로젝트에 Kotlin 코드 추가를 단순화
TypeScript 정의 생성은 특히 비즈니스 로직 공유 사용 사례에 가치가 있어요.
컴파일러는 @JsExport로 표시된 모든 최상위 선언을 수집하고 .d.ts 파일에서 TypeScript 정의를 자동으로 생성해요.
TypeScript 정의를 생성하려면 Gradle 빌드 파일에서 명시적으로 구성해요. js {} 블록의 build.gradle.kts 파일에 generateTypeScriptDefinitions() 함수를 추가해요.
kotlin {
js {
binaries.executable()
browser {
}
generateTypeScriptDefinitions()
}
}
정의는 webpack 처리를 거치지 않은 해당 JavaScript 코드와 함께 build/js/packages/<package_name>/kotlin 디렉터리에서 찾을 수 있어요.
의존성
의존성을 선언하려면 build.gradle(.kts) 파일의 jsMain 소스 세트에서 dependencies {} 블록을 사용해요.
kotlin {
sourceSets {
jsMain {
dependencies {
implementation("org.example.myproject:1.1.0")
}
}
}
}
kotlin {
sourceSets {
jsMain {
dependencies {
implementation 'org.example.myproject:1.1.0'
}
}
}
}
Kotlin/JS용 아티팩트를 포함하는 라이브러리만 의존성으로 사용할 수 있어요. 의존성을 해석하려면 build.gradle(.kts) 파일의 repositories {} 블록에서 Gradle이 검색할 저장소를 선언해요. 예를 들어:
repositories {
mavenCentral()
}
추가하는 라이브러리가 npm 패키지에 의존한다면, Gradle이 이런 전이 의존성도 자동으로 해석해요.
Kotlin 표준 라이브러리
표준 라이브러리에 대한 의존성은 자동으로 추가돼요. 표준 라이브러리 버전은 Kotlin Multiplatform 플러그인 버전과 같아요.
멀티플랫폼 테스트를 위해 kotlin.test API를 사용할 수 있어요. 멀티플랫폼 프로젝트를 만들 때 commonTest에서 의존성 하나만 사용해서 모든 소스 세트에 테스트 의존성을 추가할 수 있어요.
kotlin {
sourceSets {
commonTest.dependencies {
implementation(kotlin("test")) // Brings all the platform dependencies automatically
}
}
}
kotlin {
sourceSets {
commonTest {
dependencies {
implementation kotlin("test") // Brings all the platform dependencies automatically
}
}
}
}
npm 의존성
JavaScript 세계에서 의존성을 관리하는 가장 흔한 방법은 npm이에요. npm은 가장 큰 공개 JavaScript 모듈 저장소를 제공해요.
Kotlin Multiplatform Gradle 플러그인을 사용하면 다른 의존성을 선언하듯 Gradle 빌드 스크립트에서 npm 의존성을 선언할 수 있어요.
npm 의존성을 선언하려면 의존성 선언 안에서 npm() 함수에 이름과 버전을 전달해요. npm의 semver 문법에 기반한 하나 이상의 버전 범위도 지정할 수 있어요.
kotlin {
sourceSets {
jsMain {
dependencies {
implementation(npm("core-js", "^3.38.1"))
}
}
}
}
kotlin {
sourceSets {
jsMain {
dependencies {
implementation npm('core-js', '^3.38.1')
}
}
}
}
기본적으로 플러그인은 npm 의존성을 다운로드하고 설치하는 데 Yarn 패키지 매니저의 별도 인스턴스를 사용해요. 추가 구성 없이 바로 동작하지만, 특정 요구에 맞게 튜닝할 수도 있어요.
대신 npm 패키지 매니저를 직접 사용해서 npm 의존성을 다룰 수도 있어요. 패키지 매니저로 npm을 사용하려면 gradle.properties 파일에 다음 프로퍼티를 설정해요.
kotlin.js.yarn=false
일반 의존성 외에도 Gradle DSL에서 사용할 수 있는 의존성 유형이 세 가지 더 있어요. 각 유형의 의존성을 언제 가장 잘 쓸 수 있는지 알아보려면 npm에서 연결된 공식 문서를 참고해요.
devDependencies—devNpm(...)을 통해optionalDependencies—optionalNpm(...)을 통해peerDependencies—peerNpm(...)을 통해
npm 의존성이 설치되면 Calling JS from Kotlin에 설명된 대로 코드에서 그 API를 사용할 수 있어요.
run 태스크
Kotlin Multiplatform Gradle 플러그인은 추가 구성 없이 순수 Kotlin/JS 프로젝트를 실행할 수 있게 해 주는 jsBrowserDevelopmentRun 태스크를 제공해요.
브라우저에서 Kotlin/JS 프로젝트를 실행하려면 이 태스크가 browserDevelopmentRun 태스크(멀티플랫폼 프로젝트에서도 사용 가능)의 별칭이에요. 이 태스크는 JavaScript 아티팩트를 서빙하기 위해 webpack-dev-server를 사용해요. webpack-dev-server가 사용하는 구성을 커스터마이즈하고 싶다면(예: 서버가 실행되는 포트 조정), webpack 구성 파일을 사용해요.
Node.js를 타깃으로 하는 Kotlin/JS 프로젝트를 실행하려면 nodeRun 태스크의 별칭인 jsNodeDevelopmentRun 태스크를 사용해요.
프로젝트를 실행하려면 표준 라이프사이클 jsBrowserDevelopmentRun 태스크 또는 그에 대응하는 별칭을 실행해요.
./gradlew jsBrowserDevelopmentRun
소스 파일을 변경한 뒤 애플리케이션의 재빌드를 자동으로 트리거하려면 Gradle continuous build 기능을 사용해요.
./gradlew jsBrowserDevelopmentRun --continuous
또는
./gradlew jsBrowserDevelopmentRun -t
프로젝트 빌드가 성공하면 webpack-dev-server가 브라우저 페이지를 자동으로 새로고침해요.
test 태스크
Kotlin Multiplatform Gradle 플러그인은 프로젝트의 테스트 인프라를 자동으로 설정해요. 필요한 테스트 러너와 기타 의존성을 다운로드하고 설치해요.
브라우저 프로젝트에서는 Karma 테스트 러너와 새로운 DSL for browser testing 중에서 선택할 수 있어요. Node.js 프로젝트에서는 Mocha 테스트 프레임워크를 사용할 수 있어요.
플러그인은 또한 유용한 테스트 기능을 제공해요. 예를 들어:
- 소스 맵 생성
- 테스트 리포트 생성
- 콘솔에서의 테스트 실행 결과
Karma
Karma 프로젝트는 deprecated 처리됐어요. 새 기능이나 버그 수정은 기대되지 않아요. 브라우저 테스트의 대안으로 새로운 DSL for browser testing을 사용해 보세요.
Karma 테스트 러너를 구성하려면 build.gradle(.kts) 파일의 브라우저 testTask 안에 useKarma {} 블록을 추가해요. 예를 들어 특정 브라우저를 대상으로 테스트를 실행하려면 다음을 사용해요.
kotlin {
js {
browser {
testTask {
useKarma {
useIe()
useSafari()
useFirefox()
useChrome()
useChromeCanary()
useChromeHeadless()
usePhantomJS()
useOpera()
}
}
}
binaries.executable()
// ...
}
}
또는 gradle.properties 파일에서 브라우저용 테스트 타깃을 추가할 수 있어요.
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 for browser testing
Kotlin은 브라우저 환경에서 Kotlin/JS 테스트를 실행하기 위한 실험적 DSL을 제공해요. 기술에 구애받지 않도록 설계됐어요. 현재 구현에는 내부적으로 다음 도구들이 포함돼요.
- Playwright — Chromium, Firefox, WebKit(Safari) 브라우저 엔진을 지원하는 브라우저 드라이버 겸 배포 관리자 역할을 해요.
- Mocha — 테스트 러너 역할을 해요.
- webpack — 번들러 역할을 해요 (향후 릴리스에서 Vite로 교체될 예정이에요).
새 DSL for browser testing을 사용해 보려면 Kotlin/JS 타깃의 browser {} 안에 옵트인용 test {} 블록을 추가해요.
import org.jetbrains.kotlin.gradle.ExperimentalJsTestDsl
import kotlin.time.Duration.Companion.seconds
kotlin {
js {
browser {
@OptIn(ExperimentalJsTestDsl::class)
test {
// Configures the default timeout for all runners with kotlin.Duration
timeout = 30.seconds
// Configures headless mode using Gradle providers
headless = providers
.environmentVariable("IS_IN_CI")
.map { it.toBoolean() }
.orElse(false)
// Enables and configures a custom Chromium runner
chromium("chromium-no-webgl2") {
// Overrides the default timeout for this runner
timeout = 10.seconds
// Chromium-specific extra launch argument
launchArgs.add("--disable-webgl2")
}
// Enables the Firefox runner
firefox()
// Enable WebKit (Safari) test runner
webkit()
// Enables and configures a custom WebKit runner
webkit("headful") {
headless = false
}
}
}
}
}
새 DSL for browser testing 구성에 대한 자세한 내용은 Run tests in Kotlin/JS를 참고하세요.
Node.js
Node.js 프로젝트의 경우 Kotlin Multiplatform Gradle 플러그인이 Mocha 테스트 프레임워크를 자동으로 설정해요.
Node.js 테스트 러너가 사용하는 환경 변수를 지정하려면(예: 테스트에 외부 정보를 전달하거나 패키지 해석을 미세 조정), 빌드 파일의 testTask {} 블록 안에서 key-value 쌍과 함께 environment() 함수를 사용해요.
kotlin {
js {
nodejs {
testTask {
environment("key", "value")
}
}
}
}
테스트 실행하기
기본적으로 Kotlin Multiplatform Gradle 플러그인은 Headless Chrome을 사용해서 브라우저 테스트를 실행해요. 어떤 브라우저도 플러그인에 번들로 포함되지 않으며, 테스트 러너가 없는 브라우저를 다르게 처리해요.
- Karma를 사용하면 플러그인이 테스트를 실행하는 데 쓸 수 있도록 다른 브라우저가 이미 머신에 설치되어 있어야 해요. 지속적 통합 서버에서 Kotlin/JS 테스트를 실행한다면, 테스트 대상 브라우저도 거기에 설치되어 있는지 확인하세요.
- 새 DSL for browser testing을 사용하면 플러그인이
playwright install명령을 사용해 첫 실행 시 필요한 브라우저를 설치해요. Playwright는 이 브라우저들의 위치를 관리하며 로컬에 설치된 브라우저는 사용하지 않아요.
테스트를 실행하려면 표준 라이프사이클 check 태스크를 실행해요.
./gradlew check
테스트를 건너뛰고 싶다면 빌드 파일의 testTask {} 블록에서 비활성화해요.
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예요.
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 전역 객체예요. 스크립트에서 이를 수정해야 해요.
config.module.rules.push({
test: /\.extension$/,
loader: 'loader-name'
});
모든 webpack 구성 기능은 문서에 잘 설명되어 있어요.
실행 파일 만들기
webpack을 통해 실행 가능한 JavaScript 아티팩트를 만들기 위해 Kotlin Multiplatform Gradle 플러그인에는 jsBrowserDevelopmentWebpack과 jsBrowserProductionWebpack Gradle 태스크가 있어요.
jsBrowserDevelopmentWebpack은 개발 아티팩트를 만들어요. 이 아티팩트는 더 크지만 생성하는 데 시간이 거의 걸리지 않아요. 따라서 활발한 개발 중에는jsBrowserDevelopmentWebpack태스크를 사용해요.jsBrowserProductionWebpack은 생성된 아티팩트에 데드 코드 제거(dead code elimination)를 적용하고 결과 JavaScript 파일을 축소(Minify)해요. 시간은 더 걸리지만 더 작은 실행 파일을 생성해요. 따라서 프로덕션용 프로젝트를 준비할 때는jsBrowserProductionWebpack태스크를 사용해요.
이 두 태스크 중 하나를 실행해서 개발용 또는 프로덕션용 아티팩트를 얻어요. 생성된 파일은 다르게 지정하지 않는 한 build/kotlin-webpack에서 사용할 수 있어요.
./gradlew jsBrowserProductionWebpack
이 태스크들은 타깃이 실행 파일 생성(binaries.executable())으로 구성된 경우에만 사용할 수 있다는 점을 유의하세요.
build/dist/<targetName>/<binaryName> 디렉터리에 배포본을 생성하려면 대신 jsBrowserDistribution 태스크를 실행해요.
./gradlew jsBrowserDistribution
이 태스크는 프로젝트 리소스를 포함한 바로 사용 가능한 배포본을 생성해요.
CSS
Kotlin Multiplatform Gradle 플러그인은 webpack의 CSS와 style 로더에 대한 지원도 제공해요. 모든 옵션은 프로젝트를 빌드하는 데 사용되는 webpack 구성 파일을 직접 수정해서 바꿀 수 있지만, 가장 흔히 쓰이는 설정은 build.gradle(.kts) 파일에서 직접 사용할 수 있어요.
프로젝트에서 CSS 지원을 켜려면 commonWebpackConfig {} 블록의 Gradle 빌드 파일에서 cssSupport.enabled 옵션을 설정해요. 이 구성은 위저드로 새 프로젝트를 만들 때 기본적으로 활성화되기도 해요.
browser {
commonWebpackConfig {
cssSupport {
enabled.set(true)
}
}
}
browser {
commonWebpackConfig {
cssSupport {
it.enabled = true
}
}
}
또는 webpackTask {}, runTask {}, testTask {} 각각에 CSS 지원을 독립적으로 추가할 수 있어요.
browser {
webpackTask {
cssSupport {
enabled.set(true)
}
}
runTask {
cssSupport {
enabled.set(true)
}
}
testTask {
useKarma {
// ...
webpackConfig.cssSupport {
enabled.set(true)
}
}
}
}
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를 사용해요. 여기에서 각각 모드와 include, exclude 패턴을 정의하는 KotlinWebpackCssRules 목록을 지정할 수 있어요.
Node.js
Node.js를 타깃으로 하는 Kotlin/JS 프로젝트의 경우 플러그인이 호스트에 Node.js 환경을 자동으로 다운로드하고 설치해요. Node.js 인스턴스가 이미 있다면 기존 것을 사용할 수도 있어요.
Node.js 설정을 각 서브프로젝트별로 구성하거나 프로젝트 전체에 대해 설정할 수 있어요.
Node.js 버전 변경
현재 기본 Node.js 버전은 24.16.0이에요. 하지만 특정 서브프로젝트에 대해 다른 버전을 사용할 수 있어요. 서브프로젝트의 build.gradle(.kts) 파일에 다음 줄을 추가해요. 예를 들어:
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"
}
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 {} 블록에 같은 코드를 적용해요. 예를 들어:
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"
}
}
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) 파일에 다음 줄을 추가해요.
project.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin> {
// Set to `true` for default behavior
project.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec>().download = false
}
project.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsPlugin) {
// Set to `true` for default behavior
project.extensions.getByType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsEnvSpec).download = false
}
Yarn
기본적으로 플러그인은 빌드 시 선언한 의존성을 다운로드하고 설치하기 위해 자체 Yarn 패키지 매니저 인스턴스를 관리해요. 추가 구성 없이 바로 동작하지만, 튜닝하거나 호스트에 이미 설치된 Yarn을 사용할 수도 있어요.
추가 Yarn 기능: .yarnrc
추가 Yarn 기능을 구성하려면 프로젝트 루트에 .yarnrc 파일을 두어요. 빌드 시 자동으로 인식돼요.
예를 들어 npm 패키지용 사용자 지정 레지스트리를 사용하려면 프로젝트 루트에 .yarnrc라는 파일에 다음 줄을 추가해요.
registry "http://my.registry/api/npm/"
.yarnrc에 대해 더 알아보려면 공식 Yarn 문서를 방문하세요.
사전 설치된 Yarn 사용하기
Kotlin/JS 프로젝트를 빌드하는 호스트에 Yarn이 이미 설치되어 있다면, Kotlin Multiplatform Gradle 플러그인이 자체 Yarn 인스턴스를 설치하는 대신 그걸 사용하도록 구성할 수 있어요.
사전 설치된 Yarn 인스턴스를 사용하려면 build.gradle(.kts)에 다음 줄을 추가해요.
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootEnvSpec>().download = false
// "true" for default behavior
}
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를 통한 버전 고정(Version locking)
프로젝트 루트의 kotlin-js-store 디렉터리는 버전 고정에 필요한 yarn.lock 파일을 보관하기 위해 Kotlin Multiplatform Gradle 플러그인이 자동으로 생성해요. 이 lockfile은 Yarn 플러그인이 완전히 관리하며, kotlinNpmInstall Gradle 태스크 실행 중에 업데이트돼요.
권장 사례를 따르려면 kotlin-js-store와 그 내용을 버전 관리 시스템에 커밋해요. 이렇게 하면 모든 머신에서 정확히 같은 의존성 트리로 애플리케이션이 빌드되도록 보장해요.
필요하다면 build.gradle(.kts)에서 디렉터리와 lockfile 이름을 모두 바꿀 수 있어요.
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"
}
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'
}
lockfile 이름을 바꾸면 의존성 검사 도구가 더 이상 파일을 인식하지 못할 수 있어요.
yarn.lock에 대해 더 알아보려면 공식 Yarn 문서를 방문하세요.
yarn.lock 업데이트 보고
Kotlin/JS는 yarn.lock 파일이 업데이트되었을 때 알려 주는 Gradle 설정을 제공해요. CI 빌드 과정에서 yarn.lock이 조용히 변경되었을 때 알림을 받고 싶을 때 이 설정을 사용할 수 있어요.
YarnLockMismatchReport—yarn.lock파일의 변경을 어떻게 보고할지 지정해요. 다음 값 중 하나를 사용할 수 있어요.FAIL— 해당 Gradle 태스크를 실패시켜요. 이것이 기본값이에요.WARNING— 경고 로그에 변경 정보를 기록해요.NONE— 보고를 비활성화해요.
reportNewYarnLock— 최근 생성된yarn.lock파일을 명시적으로 보고해요. 기본적으로 이 옵션은 비활성화되어 있어요. 첫 시작 시 새yarn.lock파일을 생성하는 게 일반적인 관행이기 때문이에요. 이 옵션을 사용해서 파일이 저장소에 커밋되었는지 확인할 수 있어요.yarnLockAutoReplace— Gradle 태스크를 실행할 때마다yarn.lock을 자동으로 교체해요.
이 옵션들을 사용하려면 build.gradle(.kts)를 다음과 같이 업데이트해요.
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
}
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 의존성 설치 중 lifecycle scripts가 실행되는 것을 방지해요.
lifecycle scripts 실행을 명시적으로 활성화하려면 build.gradle(.kts)에 다음 줄을 추가해요.
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin> {
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().ignoreScripts = false
}
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 {
js {
browser {
distribution {
outputDirectory.set(projectDir.resolve("output"))
}
}
binaries.executable()
// ...
}
}
kotlin {
js {
browser {
distribution {
outputDirectory = file("$projectDir/output")
}
}
binaries.executable()
// ...
}
}
모듈 이름
(build/js/packages/myModuleName에 생성되는) JavaScript 모듈의 이름과 해당 .js, .d.ts 파일을 조정하려면 outputModuleName 옵션을 사용해요.
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에 사용자 지정 항목을 추가할 수 있어요. package.json에 사용자 지정 필드를 추가하려면 컴필레이션의 packageJson 블록에서 customField() 함수를 사용해요.
kotlin {
js {
compilations["main"].packageJson {
customField("hello", mapOf("one" to 1, "two" to 2))
}
}
}
프로젝트를 빌드하면 이 코드가 package.json 파일에 다음 블록을 추가해요.
"hello": {
"one": 1,
"two": 2
}
npm 레지스트리용 package.json 파일 작성에 대해 더 알아보려면 npm docs를 참고하세요.