diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl.kt index ef345afd653..6b23634aa9d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/dsl/KotlinJsTargetDsl.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsBinaryContainer import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsExec import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack +import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig interface KotlinJsSubTargetContainerDsl : KotlinTarget { val nodejs: KotlinJsNodeDsl @@ -83,6 +84,13 @@ interface KotlinJsSubTargetDsl { } interface KotlinJsBrowserDsl : KotlinJsSubTargetDsl { + fun commonWebpackConfig(body: KotlinWebpackConfig.() -> Unit) + fun commonWebpackConfig(fn: Closure<*>) { + commonWebpackConfig { + ConfigureUtil.configure(fn, this) + } + } + fun runTask(body: KotlinWebpack.() -> Unit) fun runTask(fn: Closure<*>) { runTask { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt index 5e3202b8ca8..e3e26df3fab 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinBrowserJsIr.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.subtargets.BrowserDistribution import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest +import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode @@ -33,8 +34,8 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : KotlinJsIrSubTarget(target, "browser"), KotlinJsBrowserDsl { - private val commonWebpackConfigurations: MutableList Unit> = mutableListOf() - private val commonRunConfigurations: MutableList Unit> = mutableListOf() + private val webpackTaskConfigurations: MutableList Unit> = mutableListOf() + private val runTaskConfigurations: MutableList Unit> = mutableListOf() private val distribution: Distribution = BrowserDistribution(project) override val testTaskDescription: String @@ -46,8 +47,24 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : } } + override fun commonWebpackConfig(body: KotlinWebpackConfig.() -> Unit) { + webpackTaskConfigurations.add { + webpackConfigAppliers.add(body) + } + runTaskConfigurations.add { + webpackConfigAppliers.add(body) + } + testTask { + onTestFrameworkSet { + if (it is KotlinKarma) { + it.webpackConfig.body() + } + } + } + } + override fun runTask(body: KotlinWebpack.() -> Unit) { - commonRunConfigurations.add(body) + runTaskConfigurations.add(body) } @ExperimentalDistributionDsl @@ -56,7 +73,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : } override fun webpackTask(body: KotlinWebpack.() -> Unit) { - commonWebpackConfigurations.add(body) + webpackTaskConfigurations.add(body) } @ExperimentalDceDsl @@ -109,7 +126,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : compilation = compilation, mode = mode, entryFileProvider = entryFileProvider, - configurationActions = commonRunConfigurations, + configurationActions = runTaskConfigurations, nodeJs = nodeJs ) } @@ -169,7 +186,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : compilation = compilation, mode = mode, entryFileProvider = entryFileProvider, - configurationActions = commonWebpackConfigurations, + configurationActions = webpackTaskConfigurations, nodeJs = nodeJs ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt index 9d8b21c7b31..d66a3073c62 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/subtargets/KotlinBrowserJs.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.gradle.targets.js.subtargets import org.gradle.api.Task -import org.gradle.api.file.RegularFile import org.gradle.api.tasks.Copy import org.gradle.api.tasks.TaskProvider import org.gradle.language.base.plugins.LifecycleBasePlugin @@ -20,6 +19,7 @@ import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest +import org.jetbrains.kotlin.gradle.targets.js.testing.karma.KotlinKarma import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode @@ -35,8 +35,8 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : KotlinJsSubTarget(target, "browser"), KotlinJsBrowserDsl { - private val commonWebpackConfigurations: MutableList Unit> = mutableListOf() - private val commonRunConfigurations: MutableList Unit> = mutableListOf() + private val webpackTaskConfigurations: MutableList Unit> = mutableListOf() + private val runTaskConfigurations: MutableList Unit> = mutableListOf() private val dceConfigurations: MutableList Unit> = mutableListOf() private val distribution: Distribution = BrowserDistribution(project) @@ -49,8 +49,24 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : } } + override fun commonWebpackConfig(body: KotlinWebpackConfig.() -> Unit) { + webpackTaskConfigurations.add { + webpackConfigAppliers.add(body) + } + runTaskConfigurations.add { + webpackConfigAppliers.add(body) + } + testTask { + onTestFrameworkSet { + if (it is KotlinKarma) { + it.webpackConfig.body() + } + } + } + } + override fun runTask(body: KotlinWebpack.() -> Unit) { - commonRunConfigurations.add(body) + runTaskConfigurations.add(body) } @ExperimentalDistributionDsl @@ -59,7 +75,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : } override fun webpackTask(body: KotlinWebpack.() -> Unit) { - commonWebpackConfigurations.add(body) + webpackTaskConfigurations.add(body) } @ExperimentalDceDsl @@ -126,7 +142,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : dceTaskProvider = dceTaskProvider, devDceTaskProvider = devDceTaskProvider, mode = type, - configurationActions = commonRunConfigurations, + configurationActions = runTaskConfigurations, nodeJs = nodeJs ) } @@ -186,7 +202,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : dceTaskProvider = dceTaskProvider, devDceTaskProvider = devDceTaskProvider, mode = type, - configurationActions = commonWebpackConfigurations, + configurationActions = webpackTaskConfigurations, nodeJs = nodeJs ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt index 26508264102..e0dbc69a9bc 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt @@ -37,6 +37,24 @@ constructor( @get:Internal var testFramework: KotlinJsTestFramework? = null + set(value) { + field = value + onTestFrameworkCallbacks.forEach { callback -> + callback(value) + } + } + + private var onTestFrameworkCallbacks: MutableList<(KotlinJsTestFramework?) -> Unit> = + mutableListOf() + + fun onTestFrameworkSet(action: (KotlinJsTestFramework?) -> Unit) { + onTestFrameworkCallbacks.add(action) + testFramework?.let { testFramework: KotlinJsTestFramework -> + onTestFrameworkCallbacks.forEach { callback -> + callback(testFramework) + } + } + } @Suppress("unused") val testFrameworkSettings: String diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt index 5e702869144..11032d2ab70 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpack.kt @@ -172,14 +172,12 @@ constructor( @Internal var generateConfigOnly: Boolean = false - private fun createRunner() = KotlinWebpackRunner( - compilation.npmProject, - configFile, - execHandleFactory, - bin, - args, - nodeArgs, - KotlinWebpackConfig( + @Input + val webpackConfigAppliers: MutableList<(KotlinWebpackConfig) -> Unit> = + mutableListOf() + + private fun createRunner(): KotlinWebpackRunner { + val config = KotlinWebpackConfig( mode = mode, entry = entry, reportEvaluatedConfigFile = if (saveEvaluatedConfigFile) evaluatedConfigFile else null, @@ -194,7 +192,20 @@ constructor( sourceMaps = sourceMaps, resolveFromModulesFirst = resolveFromModulesFirst ) - ) + + webpackConfigAppliers + .forEach { it(config) } + + return KotlinWebpackRunner( + compilation.npmProject, + configFile, + execHandleFactory, + bin, + args, + nodeArgs, + config + ) + } override val nodeModulesRequired: Boolean @Internal get() = true diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt index 8e25333fa07..ed4a71f12af 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/KotlinWebpackConfig.kt @@ -21,23 +21,23 @@ import java.io.StringWriter @Suppress("MemberVisibilityCanBePrivate") data class KotlinWebpackConfig( - val mode: Mode = Mode.DEVELOPMENT, - val entry: File? = null, - val output: KotlinWebpackOutput? = null, - val outputPath: File? = null, - val outputFileName: String? = entry?.name, - val configDirectory: File? = null, - val bundleAnalyzerReportDir: File? = null, - val reportEvaluatedConfigFile: File? = null, - val devServer: DevServer? = null, - val cssSupport: KotlinWebpackCssSupport = KotlinWebpackCssSupport(), - val devtool: String? = WebpackDevtool.EVAL_SOURCE_MAP, - val showProgress: Boolean = false, - val sourceMaps: Boolean = false, - val export: Boolean = true, - val progressReporter: Boolean = false, - val progressReporterPathFilter: String? = null, - val resolveFromModulesFirst: Boolean = false + var mode: Mode = Mode.DEVELOPMENT, + var entry: File? = null, + var output: KotlinWebpackOutput? = null, + var outputPath: File? = null, + var outputFileName: String? = entry?.name, + var configDirectory: File? = null, + var bundleAnalyzerReportDir: File? = null, + var reportEvaluatedConfigFile: File? = null, + var devServer: DevServer? = null, + var cssSupport: KotlinWebpackCssSupport = KotlinWebpackCssSupport(), + var devtool: String? = WebpackDevtool.EVAL_SOURCE_MAP, + var showProgress: Boolean = false, + var sourceMaps: Boolean = false, + var export: Boolean = true, + var progressReporter: Boolean = false, + var progressReporterPathFilter: String? = null, + var resolveFromModulesFirst: Boolean = false ) { fun getRequiredDependencies(versions: NpmVersions) = mutableSetOf().also { @@ -145,7 +145,7 @@ data class KotlinWebpackConfig( private fun Appendable.appendEvaluatedFileReport() { if (reportEvaluatedConfigFile == null) return - val filePath = reportEvaluatedConfigFile.canonicalPath.jsQuoted() + val filePath = reportEvaluatedConfigFile!!.canonicalPath.jsQuoted() //language=JavaScript 1.8 appendln( @@ -163,10 +163,10 @@ data class KotlinWebpackConfig( } private fun Appendable.appendFromConfigDir() { - if (configDirectory == null || !configDirectory.isDirectory) return + if (configDirectory == null || !configDirectory!!.isDirectory) return appendln() - appendConfigsFromDir(configDirectory) + appendConfigsFromDir(configDirectory!!) appendln() } @@ -175,7 +175,7 @@ data class KotlinWebpackConfig( entry ?: error("Entry should be defined for report") - val reportBasePath = "${bundleAnalyzerReportDir.canonicalPath}/${entry.name}" + val reportBasePath = "${bundleAnalyzerReportDir!!.canonicalPath}/${entry!!.name}" val config = BundleAnalyzerPlugin( "static", "$reportBasePath.report.html", @@ -200,7 +200,7 @@ data class KotlinWebpackConfig( if (devServer == null) return appendln("// dev server") - appendln("config.devServer = ${json(devServer)};") + appendln("config.devServer = ${json(devServer!!)};") appendln() } @@ -241,19 +241,19 @@ data class KotlinWebpackConfig( """ // entry config.entry = { - main: [${entry.canonicalPath.jsQuoted()}] + main: [${entry!!.canonicalPath.jsQuoted()}] }; config.output = { - path: ${outputPath.canonicalPath.jsQuoted()}, + path: ${outputPath!!.canonicalPath.jsQuoted()}, filename: (chunkData) => { return chunkData.chunk.name === 'main' - ? ${outputFileName.jsQuoted()} + ? ${outputFileName!!.jsQuoted()} : ${multiEntryOutput.jsQuoted()}; }, - library: "${output.library}", - libraryTarget: "${output.libraryTarget}", - globalObject: "${output.globalObject}" + library: "${output!!.library}", + libraryTarget: "${output!!.libraryTarget}", + globalObject: "${output!!.globalObject}" }; """.trimIndent() @@ -382,13 +382,13 @@ data class KotlinWebpackConfig( } private fun Appendable.appendResolveModules() { - if (!resolveFromModulesFirst || entry == null || entry.parent == null) return + if (!resolveFromModulesFirst || entry == null || entry!!.parent == null) return //language=JavaScript 1.8 appendln( """ // resolve modules - config.resolve.modules.unshift(${entry.parent.jsQuoted()}) + config.resolve.modules.unshift(${entry!!.parent.jsQuoted()}) """.trimIndent() ) @@ -409,7 +409,7 @@ data class KotlinWebpackConfig( let msg = `${"$"}{Math.trunc(p / 10)}${"$"}{Math.trunc(p % 10)}% ${"$"}{message} ${"$"}{args.join(' ')}`; ${ if (progressReporterPathFilter == null) "" else """ - msg = msg.replace(new RegExp(${progressReporterPathFilter.jsQuoted()}, 'g'), ''); + msg = msg.replace(new RegExp(${progressReporterPathFilter!!.jsQuoted()}, 'g'), ''); """.trimIndent() }; console.log(msg);