From a291895ebe313a9fe18b87c67327838b9f20ec42 Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Wed, 17 Mar 2021 17:55:44 +0300 Subject: [PATCH] [Gradle, JS] Add compatibility with webpack 4 ^KT-42921 fixed --- .../kotlin/gradle/plugin/KotlinProperties.kt | 16 +++++++ .../kotlin/gradle/targets/js/NpmVersions.kt | 2 + .../gradle/targets/js/ir/KotlinBrowserJsIr.kt | 12 ++++- .../targets/js/subtargets/KotlinBrowserJs.kt | 12 ++++- .../targets/js/testing/karma/KotlinKarma.kt | 21 +++++++-- .../targets/js/webpack/KotlinWebpack.kt | 7 ++- .../targets/js/webpack/KotlinWebpackConfig.kt | 31 +++++++++++-- .../targets/js/webpack/WebpackMajorVersion.kt | 45 +++++++++++++++++++ 8 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/WebpackMajorVersion.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt index a51ceec3c50..a6aae5eb0fb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt @@ -15,6 +15,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.targets.js.dukat.ExternalsOutputFormat import org.jetbrains.kotlin.gradle.targets.js.dukat.ExternalsOutputFormat.Companion.externalsOutputFormatProperty +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion.Companion.warningMessage import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile @@ -248,6 +250,20 @@ internal class PropertiesProvider private constructor(private val project: Proje val jsCompiler: KotlinJsCompilerType get() = property(jsCompilerProperty)?.let { KotlinJsCompilerType.byArgumentOrNull(it) } ?: KotlinJsCompilerType.LEGACY + /** + * Use Webpack 4 for compatibility + */ + val webpackMajorVersion: WebpackMajorVersion + get() = property(WebpackMajorVersion.webpackMajorVersion)?.let { WebpackMajorVersion.byArgument(it) } + ?.also { version -> + if (!WebpackMajorVersion.webpackVersionWarning && version != WebpackMajorVersion.DEFAULT) { + WebpackMajorVersion.webpackVersionWarning = true + project.logger.warn(WebpackMajorVersion.warningMessage) + } + } + ?: WebpackMajorVersion.DEFAULT + + /** * Default mode of generating of Dukat */ diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/NpmVersions.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/NpmVersions.kt index 94d811ab074..5f01cbe92f4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/NpmVersions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/NpmVersions.kt @@ -12,10 +12,12 @@ package org.jetbrains.kotlin.gradle.targets.js class NpmVersions { val dukat = NpmPackageVersion("dukat", "0.5.8-rc.4") val webpack = NpmPackageVersion("webpack", "5.26.2") + val webpack4 = NpmPackageVersion("webpack", "4.44.1") val webpackCli = NpmPackageVersion("webpack-cli", "4.5.0") val webpackBundleAnalyzer = NpmPackageVersion("webpack-bundle-analyzer", "4.4.0") val webpackDevServer = NpmPackageVersion("webpack-dev-server", "3.11.2") val sourceMapLoader = NpmPackageVersion("source-map-loader", "2.0.1") + val sourceMapLoader1 = NpmPackageVersion("source-map-loader", "1.1.0") val sourceMapSupport = NpmPackageVersion("source-map-support", "0.5.19") val cssLoader = NpmPackageVersion("css-loader", "5.1.3") val styleLoader = NpmPackageVersion("style-loader", "2.0.0") 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 29f9758ed87..00b8913623c 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 @@ -10,6 +10,7 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.Copy import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.gradle.dsl.KotlinJsDce +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDceDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode @@ -22,6 +23,8 @@ 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 import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackDevtool +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion.Companion.choose import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.utils.newFileProperty import java.io.File @@ -34,6 +37,10 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : private val webpackTaskConfigurations: MutableList Unit> = mutableListOf() private val runTaskConfigurations: MutableList Unit> = mutableListOf() + private val propertiesProvider = PropertiesProvider(project) + private val webpackMajorVersion + get() = propertiesProvider.webpackMajorVersion + override val testTaskDescription: String get() = "Run all ${target.name} tests inside browser using karma and webpack" @@ -99,7 +106,10 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) : .resolve(binary.linkTask.get().outputFile.name) } - task.args.add(0, "serve") + webpackMajorVersion.choose( + { task.args.add(0, "serve") }, + { task.bin = "webpack-dev-server/bin/webpack-dev-server.js" } + )() task.description = "start ${mode.name.toLowerCase()} webpack dev server" task.devServer = KotlinWebpackConfig.DevServer( 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 7979f782b82..47577afcdce 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 @@ -12,6 +12,7 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.gradle.dsl.KotlinJsDce import org.jetbrains.kotlin.gradle.plugin.COMPILER_CLASSPATH_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget import org.jetbrains.kotlin.gradle.targets.js.dsl.* @@ -25,6 +26,8 @@ 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 import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackDevtool +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion.Companion.choose import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName @@ -40,6 +43,9 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : private val runTaskConfigurations: MutableList Unit> = mutableListOf() private val dceConfigurations: MutableList Unit> = mutableListOf() private val distribution: Distribution = DefaultDistribution(project) + private val propertiesProvider = PropertiesProvider(project) + private val webpackMajorVersion + get() = propertiesProvider.webpackMajorVersion override val testTaskDescription: String get() = "Run all ${target.name} tests inside browser using karma and webpack" @@ -128,7 +134,11 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) : ), listOf(compilation) ) { task -> - task.args.add(0, "serve") + webpackMajorVersion.choose( + { task.args.add(0, "serve") }, + { task.bin = "webpack-dev-server/bin/webpack-dev-server.js" } + )() + task.description = "start ${type.name.toLowerCase()} webpack dev server" task.devServer = KotlinWebpackConfig.DevServer( diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt index 8af5beb909b..6c74ab1ba50 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/karma/KotlinKarma.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.gradle.internal.processLogMessage import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesClientSettings import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutor.Companion.TC_PROJECT_PROPERTY +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.NpmPackageVersion import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency @@ -30,6 +31,7 @@ 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.* import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion.Companion.choose import org.jetbrains.kotlin.gradle.tasks.KotlinTest import org.jetbrains.kotlin.gradle.testing.internal.reportsDir import org.jetbrains.kotlin.gradle.utils.isConfigurationCacheAvailable @@ -76,13 +78,16 @@ class KotlinKarma( override val settingsState: String get() = "KotlinKarma($config)" + private val webpackMajorVersion = PropertiesProvider(project).webpackMajorVersion + val webpackConfig = KotlinWebpackConfig( configDirectory = project.projectDir.resolve("webpack.config.d"), sourceMaps = true, devtool = null, export = false, progressReporter = true, - progressReporterPathFilter = nodeJs.rootPackageDir.absolutePath + progressReporterPathFilter = nodeJs.rootPackageDir.absolutePath, + webpackMajorVersion = webpackMajorVersion ) init { @@ -200,10 +205,20 @@ class KotlinKarma( private fun useWebpack() { requiredDependencies.add(versions.karmaWebpack) - requiredDependencies.add(versions.webpack) + requiredDependencies.add( + webpackMajorVersion.choose( + versions.webpack, + versions.webpack4 + ) + ) requiredDependencies.add(versions.webpackCli) requiredDependencies.add(versions.formatUtil) - requiredDependencies.add(versions.sourceMapLoader) + requiredDependencies.add( + webpackMajorVersion.choose( + versions.sourceMapLoader, + versions.sourceMapLoader1 + ) + ) addPreprocessor("webpack") confJsWriters.add { 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 0cac1db9c50..4a3a0c5645d 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 @@ -18,6 +18,7 @@ import org.gradle.deployment.internal.DeploymentHandle import org.gradle.deployment.internal.DeploymentRegistry import org.gradle.process.internal.ExecHandle import org.gradle.process.internal.ExecHandleFactory +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin @@ -205,6 +206,9 @@ constructor( @Nested val synthConfig = KotlinWebpackConfig() + @Input + val webpackMajorVersion = PropertiesProvider(project).webpackMajorVersion + fun webpackConfigApplier(body: KotlinWebpackConfig.() -> Unit) { synthConfig.body() webpackConfigAppliers.add(body) @@ -227,7 +231,8 @@ constructor( devServer = devServer, devtool = devtool, sourceMaps = sourceMaps, - resolveFromModulesFirst = resolveFromModulesFirst + resolveFromModulesFirst = resolveFromModulesFirst, + webpackMajorVersion = webpackMajorVersion ) webpackConfigAppliers 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 29bc2e1cc6a..a2b8a9b6a6b 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 @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.targets.js.jsQuoted import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackCssMode.EXTRACT import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackCssMode.IMPORT import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackCssMode.INLINE +import org.jetbrains.kotlin.gradle.targets.js.webpack.WebpackMajorVersion.Companion.choose import java.io.File import java.io.Serializable import java.io.StringWriter @@ -63,7 +64,9 @@ data class KotlinWebpackConfig( @Optional var progressReporterPathFilter: String? = null, @Input - var resolveFromModulesFirst: Boolean = false + var resolveFromModulesFirst: Boolean = false, + @Input + val webpackMajorVersion: WebpackMajorVersion = WebpackMajorVersion.V5 ) { @get:Input @get:Optional @@ -93,7 +96,12 @@ data class KotlinWebpackConfig( fun getRequiredDependencies(versions: NpmVersions) = mutableSetOf().also { it.add(versions.kotlinJsTestRunner) - it.add(versions.webpack) + it.add( + webpackMajorVersion.choose( + versions.webpack, + versions.webpack4 + ) + ) it.add(versions.webpackCli) it.add(versions.formatUtil) @@ -102,7 +110,12 @@ data class KotlinWebpackConfig( } if (sourceMaps) { - it.add(versions.sourceMapLoader) + it.add( + webpackMajorVersion.choose( + versions.sourceMapLoader, + versions.sourceMapLoader1 + ) + ) } if (devServer != null) { @@ -269,7 +282,17 @@ data class KotlinWebpackConfig( enforce: "pre" }); config.devtool = ${devtool?.let { "'$it'" } ?: false}; - config.ignoreWarnings = [/Failed to parse source map/] + ${ + webpackMajorVersion.choose( + "config.ignoreWarnings = [/Failed to parse source map/]", + """ + config.stats = config.stats || {} + Object.assign(config.stats, config.stats, { + warningsFilter: [/Failed to parse source map/] + }) + """ + ) + } """.trimIndent() ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/WebpackMajorVersion.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/WebpackMajorVersion.kt new file mode 100644 index 00000000000..6bb6926cb30 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/js/webpack/WebpackMajorVersion.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.targets.js.webpack + +enum class WebpackMajorVersion( + val value: String +) { + V4("4"), + V5("5"); + + companion object { + val DEFAULT = V5 + + const val webpackMajorVersion = "kotlin.js.webpack.major.version" + + const val warningMessage = "Default webpack version now is 5. Support of webpack 4 is deprecated." + + var webpackVersionWarning = false + + fun byArgumentOrNull(argument: String): WebpackMajorVersion? = + when (argument) { + "4" -> V4 + "5" -> V5 + else -> null + } + + fun byArgument(argument: String): WebpackMajorVersion = + byArgumentOrNull(argument) + ?: throw IllegalArgumentException( + "This webpack major version is not supported. Use [${WebpackMajorVersion.values().toList().joinToString { it.value }}]" + ) + + fun WebpackMajorVersion.choose( + defaultValue: T, + v4Value: T + ): T = + when (this) { + V5 -> defaultValue + V4 -> v4Value + } + } +} \ No newline at end of file