Support Kotlin/JS DCE in new MPP
Issue #KT-27196 Fixed
This commit is contained in:
+16
@@ -846,4 +846,20 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJsDceInMpp() = with(Project("new-mpp-js-dce", gradleVersion)) {
|
||||
build("runRhino") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":mainProject:runDceNodeJsKotlin")
|
||||
|
||||
val pathPrefix = "mainProject/build/kotlin-js-min/nodeJs/main"
|
||||
assertFileExists("$pathPrefix/exampleapp.js.map")
|
||||
assertFileExists("$pathPrefix/examplelib.js.map")
|
||||
assertFileContains("$pathPrefix/exampleapp.js.map", "\"../../../../src/nodeJsMain/kotlin/exampleapp/main.kt\"")
|
||||
|
||||
assertFileExists("$pathPrefix/kotlin.js")
|
||||
assertTrue(fileInWorkingDir("$pathPrefix/kotlin.js").length() < 500 * 1000, "Looks like kotlin.js file was not minified by DCE")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin-multiplatform'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin.targets.fromPreset(kotlin.presets.js, 'nodeJs')
|
||||
|
||||
dependencies {
|
||||
nodeJsMainApi "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
|
||||
}
|
||||
|
||||
compileKotlinNodeJs.kotlinOptions.outputFile = "${buildDir}/examplelib.js"
|
||||
compileKotlinNodeJs.kotlinOptions.sourceMap = true
|
||||
|
||||
nodeJsJar {
|
||||
from buildDir
|
||||
include "**/*.js"
|
||||
include "**/*.js.map"
|
||||
}
|
||||
|
||||
nodeJsJar.dependsOn(compileKotlinNodeJs)
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package examplelib
|
||||
|
||||
fun foo() = "foo"
|
||||
|
||||
fun bar() = "bar"
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "kotlin-multiplatform"
|
||||
apply plugin: "kotlin-dce-js"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin.targets.fromPreset(kotlin.presets.js, 'nodeJs')
|
||||
|
||||
dependencies {
|
||||
nodeJsImplementation project(":libraryProject")
|
||||
nodeJsImplementation "org.jetbrains.kotlin:kotlin-stdlib-js"
|
||||
nodeJsImplementation "org.mozilla:rhino:1.7.7.1"
|
||||
}
|
||||
|
||||
compileKotlinNodeJs.kotlinOptions.sourceMap = true
|
||||
compileKotlinNodeJs.kotlinOptions.outputFile = "${buildDir}/exampleapp.js"
|
||||
compileKotlinNodeJs.kotlinOptions.suppressWarnings = true
|
||||
compileKotlinNodeJs.kotlinOptions.verbose = true
|
||||
runDceNodeJsKotlin.keep("exampleapp.exampleapp.status")
|
||||
|
||||
task runRhino(type: JavaExec) {
|
||||
classpath = kotlin.targets.nodeJs.compilations.main.runtimeDependencyFiles
|
||||
workingDir = "${buildDir}"
|
||||
main = 'org.mozilla.javascript.tools.shell.Main'
|
||||
args = ["-opt", "-1",
|
||||
"-f", "kotlin-js-min/nodeJs/main/kotlin.js",
|
||||
"-f", "kotlin-js-min/nodeJs/main/examplelib.js",
|
||||
"-f", "kotlin-js-min/nodeJs/main/exampleapp.js",
|
||||
"-f", "../check.js"]
|
||||
}
|
||||
|
||||
runRhino.dependsOn(runDceNodeJsKotlin)
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
(function() {
|
||||
var status = exampleapp.exampleapp.status;
|
||||
if (status !== "foo") {
|
||||
throw new Error("Unexpected status: " + status);
|
||||
}
|
||||
})();
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package exampleapp
|
||||
|
||||
import examplelib.*
|
||||
|
||||
var status = "failure"
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
status = foo()
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
include 'mainProject', 'libraryProject'
|
||||
+36
-10
@@ -18,33 +18,58 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleJavaTargetExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJsDce
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import java.io.File
|
||||
|
||||
class KotlinJsDcePlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.pluginManager.apply(Kotlin2JsPluginWrapper::class.java)
|
||||
val kotlinExtension = project.multiplatformExtension ?: run {
|
||||
project.pluginManager.apply(Kotlin2JsPluginWrapper::class.java)
|
||||
project.kotlinExtension as KotlinSingleJavaTargetExtension
|
||||
}
|
||||
|
||||
val javaPluginConvention = project.convention.getPlugin(JavaPluginConvention::class.java)
|
||||
javaPluginConvention.sourceSets.forEach { processSourceSet(project, it) }
|
||||
fun forEachJsTarget(action: (KotlinTarget) -> Unit) {
|
||||
when (kotlinExtension) {
|
||||
is KotlinSingleJavaTargetExtension -> action(kotlinExtension.target)
|
||||
is KotlinMultiplatformExtension ->
|
||||
kotlinExtension.targets
|
||||
.matching { it.platformType == KotlinPlatformType.js }
|
||||
.all { action(it) }
|
||||
}
|
||||
}
|
||||
|
||||
forEachJsTarget {
|
||||
it.compilations.all { processCompilation(project, it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun processSourceSet(project: Project, sourceSet: SourceSet) {
|
||||
val kotlinTaskName = sourceSet.getCompileTaskName("kotlin2Js")
|
||||
private fun processCompilation(project: Project, kotlinCompilation: KotlinCompilation) {
|
||||
val kotlinTaskName = kotlinCompilation.compileKotlinTaskName
|
||||
val kotlinTask = project.tasks.findByName(kotlinTaskName) as? Kotlin2JsCompile ?: return
|
||||
val dceTaskName = sourceSet.getTaskName(DCE_TASK_PREFIX, TASK_SUFFIX)
|
||||
val dceTaskName = lowerCamelCaseName(
|
||||
DCE_TASK_PREFIX,
|
||||
kotlinCompilation.target.disambiguationClassifier,
|
||||
kotlinCompilation.name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
||||
if (kotlinCompilation.target is KotlinWithJavaTarget) TASK_SUFFIX else MPP_TASK_SUFFIX
|
||||
)
|
||||
val dceTask = project.tasks.create(dceTaskName, KotlinJsDce::class.java).also {
|
||||
it.dependsOn(kotlinTask)
|
||||
project.tasks.findByName("build")!!.dependsOn(it)
|
||||
}
|
||||
|
||||
project.afterEvaluate {
|
||||
val outputDir = File(File(project.buildDir, DEFAULT_OUT_DIR), sourceSet.name)
|
||||
val outputDir = project.buildDir
|
||||
.resolve(DEFAULT_OUT_DIR)
|
||||
.resolve(kotlinCompilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty() + kotlinCompilation.name)
|
||||
|
||||
val configuration = project.configurations.findByName(sourceSet.compileConfigurationName)!!
|
||||
val configuration = project.configurations.getByName(kotlinCompilation.compileDependencyConfigurationName)
|
||||
|
||||
with (dceTask) {
|
||||
classpath = configuration
|
||||
@@ -56,6 +81,7 @@ class KotlinJsDcePlugin : Plugin<Project> {
|
||||
|
||||
companion object {
|
||||
private const val TASK_SUFFIX = "kotlinJs"
|
||||
private const val MPP_TASK_SUFFIX = "kotlin"
|
||||
private const val DCE_TASK_PREFIX = "runDce"
|
||||
private const val DEFAULT_OUT_DIR = "kotlin-js-min"
|
||||
}
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.presetName
|
||||
|
||||
internal val Project.multiplatformExtension get(): KotlinMultiplatformExtension? =
|
||||
project.extensions.getByName("kotlin") as KotlinMultiplatformExtension
|
||||
project.extensions.findByName("kotlin") as? KotlinMultiplatformExtension
|
||||
|
||||
class KotlinMultiplatformPlugin(
|
||||
private val buildOutputCleanupRegistry: BuildOutputCleanupRegistry,
|
||||
|
||||
Reference in New Issue
Block a user