[Gradle, JS] Common webpack configuration

^KT-39825 fixed
This commit is contained in:
Ilya Goncharov
2020-07-16 17:28:53 +03:00
parent a2b26c00a1
commit 9a3ae4f4fa
6 changed files with 123 additions and 53 deletions
@@ -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.nodejs.NodeJsExec
import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest 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.KotlinWebpack
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
interface KotlinJsSubTargetContainerDsl : KotlinTarget { interface KotlinJsSubTargetContainerDsl : KotlinTarget {
val nodejs: KotlinJsNodeDsl val nodejs: KotlinJsNodeDsl
@@ -83,6 +84,13 @@ interface KotlinJsSubTargetDsl {
} }
interface KotlinJsBrowserDsl : 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(body: KotlinWebpack.() -> Unit)
fun runTask(fn: Closure<*>) { fun runTask(fn: Closure<*>) {
runTask { runTask {
@@ -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.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.subtargets.BrowserDistribution 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.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.KotlinWebpack
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig 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.KotlinWebpackConfig.Mode
@@ -33,8 +34,8 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
KotlinJsIrSubTarget(target, "browser"), KotlinJsIrSubTarget(target, "browser"),
KotlinJsBrowserDsl { KotlinJsBrowserDsl {
private val commonWebpackConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf() private val webpackTaskConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val commonRunConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf() private val runTaskConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val distribution: Distribution = BrowserDistribution(project) private val distribution: Distribution = BrowserDistribution(project)
override val testTaskDescription: String 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) { override fun runTask(body: KotlinWebpack.() -> Unit) {
commonRunConfigurations.add(body) runTaskConfigurations.add(body)
} }
@ExperimentalDistributionDsl @ExperimentalDistributionDsl
@@ -56,7 +73,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
} }
override fun webpackTask(body: KotlinWebpack.() -> Unit) { override fun webpackTask(body: KotlinWebpack.() -> Unit) {
commonWebpackConfigurations.add(body) webpackTaskConfigurations.add(body)
} }
@ExperimentalDceDsl @ExperimentalDceDsl
@@ -109,7 +126,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
compilation = compilation, compilation = compilation,
mode = mode, mode = mode,
entryFileProvider = entryFileProvider, entryFileProvider = entryFileProvider,
configurationActions = commonRunConfigurations, configurationActions = runTaskConfigurations,
nodeJs = nodeJs nodeJs = nodeJs
) )
} }
@@ -169,7 +186,7 @@ open class KotlinBrowserJsIr @Inject constructor(target: KotlinJsIrTarget) :
compilation = compilation, compilation = compilation,
mode = mode, mode = mode,
entryFileProvider = entryFileProvider, entryFileProvider = entryFileProvider,
configurationActions = commonWebpackConfigurations, configurationActions = webpackTaskConfigurations,
nodeJs = nodeJs nodeJs = nodeJs
) )
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.gradle.targets.js.subtargets package org.jetbrains.kotlin.gradle.targets.js.subtargets
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.file.RegularFile
import org.gradle.api.tasks.Copy import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.gradle.language.base.plugins.LifecycleBasePlugin 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.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject 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.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.KotlinWebpack
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig 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.KotlinWebpackConfig.Mode
@@ -35,8 +35,8 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
KotlinJsSubTarget(target, "browser"), KotlinJsSubTarget(target, "browser"),
KotlinJsBrowserDsl { KotlinJsBrowserDsl {
private val commonWebpackConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf() private val webpackTaskConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val commonRunConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf() private val runTaskConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val dceConfigurations: MutableList<KotlinJsDce.() -> Unit> = mutableListOf() private val dceConfigurations: MutableList<KotlinJsDce.() -> Unit> = mutableListOf()
private val distribution: Distribution = BrowserDistribution(project) 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) { override fun runTask(body: KotlinWebpack.() -> Unit) {
commonRunConfigurations.add(body) runTaskConfigurations.add(body)
} }
@ExperimentalDistributionDsl @ExperimentalDistributionDsl
@@ -59,7 +75,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
} }
override fun webpackTask(body: KotlinWebpack.() -> Unit) { override fun webpackTask(body: KotlinWebpack.() -> Unit) {
commonWebpackConfigurations.add(body) webpackTaskConfigurations.add(body)
} }
@ExperimentalDceDsl @ExperimentalDceDsl
@@ -126,7 +142,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
dceTaskProvider = dceTaskProvider, dceTaskProvider = dceTaskProvider,
devDceTaskProvider = devDceTaskProvider, devDceTaskProvider = devDceTaskProvider,
mode = type, mode = type,
configurationActions = commonRunConfigurations, configurationActions = runTaskConfigurations,
nodeJs = nodeJs nodeJs = nodeJs
) )
} }
@@ -186,7 +202,7 @@ open class KotlinBrowserJs @Inject constructor(target: KotlinJsTarget) :
dceTaskProvider = dceTaskProvider, dceTaskProvider = dceTaskProvider,
devDceTaskProvider = devDceTaskProvider, devDceTaskProvider = devDceTaskProvider,
mode = type, mode = type,
configurationActions = commonWebpackConfigurations, configurationActions = webpackTaskConfigurations,
nodeJs = nodeJs nodeJs = nodeJs
) )
} }
@@ -37,6 +37,24 @@ constructor(
@get:Internal @get:Internal
var testFramework: KotlinJsTestFramework? = null 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") @Suppress("unused")
val testFrameworkSettings: String val testFrameworkSettings: String
@@ -172,14 +172,12 @@ constructor(
@Internal @Internal
var generateConfigOnly: Boolean = false var generateConfigOnly: Boolean = false
private fun createRunner() = KotlinWebpackRunner( @Input
compilation.npmProject, val webpackConfigAppliers: MutableList<(KotlinWebpackConfig) -> Unit> =
configFile, mutableListOf()
execHandleFactory,
bin, private fun createRunner(): KotlinWebpackRunner {
args, val config = KotlinWebpackConfig(
nodeArgs,
KotlinWebpackConfig(
mode = mode, mode = mode,
entry = entry, entry = entry,
reportEvaluatedConfigFile = if (saveEvaluatedConfigFile) evaluatedConfigFile else null, reportEvaluatedConfigFile = if (saveEvaluatedConfigFile) evaluatedConfigFile else null,
@@ -194,7 +192,20 @@ constructor(
sourceMaps = sourceMaps, sourceMaps = sourceMaps,
resolveFromModulesFirst = resolveFromModulesFirst resolveFromModulesFirst = resolveFromModulesFirst
) )
)
webpackConfigAppliers
.forEach { it(config) }
return KotlinWebpackRunner(
compilation.npmProject,
configFile,
execHandleFactory,
bin,
args,
nodeArgs,
config
)
}
override val nodeModulesRequired: Boolean override val nodeModulesRequired: Boolean
@Internal get() = true @Internal get() = true
@@ -21,23 +21,23 @@ import java.io.StringWriter
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
data class KotlinWebpackConfig( data class KotlinWebpackConfig(
val mode: Mode = Mode.DEVELOPMENT, var mode: Mode = Mode.DEVELOPMENT,
val entry: File? = null, var entry: File? = null,
val output: KotlinWebpackOutput? = null, var output: KotlinWebpackOutput? = null,
val outputPath: File? = null, var outputPath: File? = null,
val outputFileName: String? = entry?.name, var outputFileName: String? = entry?.name,
val configDirectory: File? = null, var configDirectory: File? = null,
val bundleAnalyzerReportDir: File? = null, var bundleAnalyzerReportDir: File? = null,
val reportEvaluatedConfigFile: File? = null, var reportEvaluatedConfigFile: File? = null,
val devServer: DevServer? = null, var devServer: DevServer? = null,
val cssSupport: KotlinWebpackCssSupport = KotlinWebpackCssSupport(), var cssSupport: KotlinWebpackCssSupport = KotlinWebpackCssSupport(),
val devtool: String? = WebpackDevtool.EVAL_SOURCE_MAP, var devtool: String? = WebpackDevtool.EVAL_SOURCE_MAP,
val showProgress: Boolean = false, var showProgress: Boolean = false,
val sourceMaps: Boolean = false, var sourceMaps: Boolean = false,
val export: Boolean = true, var export: Boolean = true,
val progressReporter: Boolean = false, var progressReporter: Boolean = false,
val progressReporterPathFilter: String? = null, var progressReporterPathFilter: String? = null,
val resolveFromModulesFirst: Boolean = false var resolveFromModulesFirst: Boolean = false
) { ) {
fun getRequiredDependencies(versions: NpmVersions) = fun getRequiredDependencies(versions: NpmVersions) =
mutableSetOf<RequiredKotlinJsDependency>().also { mutableSetOf<RequiredKotlinJsDependency>().also {
@@ -145,7 +145,7 @@ data class KotlinWebpackConfig(
private fun Appendable.appendEvaluatedFileReport() { private fun Appendable.appendEvaluatedFileReport() {
if (reportEvaluatedConfigFile == null) return if (reportEvaluatedConfigFile == null) return
val filePath = reportEvaluatedConfigFile.canonicalPath.jsQuoted() val filePath = reportEvaluatedConfigFile!!.canonicalPath.jsQuoted()
//language=JavaScript 1.8 //language=JavaScript 1.8
appendln( appendln(
@@ -163,10 +163,10 @@ data class KotlinWebpackConfig(
} }
private fun Appendable.appendFromConfigDir() { private fun Appendable.appendFromConfigDir() {
if (configDirectory == null || !configDirectory.isDirectory) return if (configDirectory == null || !configDirectory!!.isDirectory) return
appendln() appendln()
appendConfigsFromDir(configDirectory) appendConfigsFromDir(configDirectory!!)
appendln() appendln()
} }
@@ -175,7 +175,7 @@ data class KotlinWebpackConfig(
entry ?: error("Entry should be defined for report") entry ?: error("Entry should be defined for report")
val reportBasePath = "${bundleAnalyzerReportDir.canonicalPath}/${entry.name}" val reportBasePath = "${bundleAnalyzerReportDir!!.canonicalPath}/${entry!!.name}"
val config = BundleAnalyzerPlugin( val config = BundleAnalyzerPlugin(
"static", "static",
"$reportBasePath.report.html", "$reportBasePath.report.html",
@@ -200,7 +200,7 @@ data class KotlinWebpackConfig(
if (devServer == null) return if (devServer == null) return
appendln("// dev server") appendln("// dev server")
appendln("config.devServer = ${json(devServer)};") appendln("config.devServer = ${json(devServer!!)};")
appendln() appendln()
} }
@@ -241,19 +241,19 @@ data class KotlinWebpackConfig(
""" """
// entry // entry
config.entry = { config.entry = {
main: [${entry.canonicalPath.jsQuoted()}] main: [${entry!!.canonicalPath.jsQuoted()}]
}; };
config.output = { config.output = {
path: ${outputPath.canonicalPath.jsQuoted()}, path: ${outputPath!!.canonicalPath.jsQuoted()},
filename: (chunkData) => { filename: (chunkData) => {
return chunkData.chunk.name === 'main' return chunkData.chunk.name === 'main'
? ${outputFileName.jsQuoted()} ? ${outputFileName!!.jsQuoted()}
: ${multiEntryOutput.jsQuoted()}; : ${multiEntryOutput.jsQuoted()};
}, },
library: "${output.library}", library: "${output!!.library}",
libraryTarget: "${output.libraryTarget}", libraryTarget: "${output!!.libraryTarget}",
globalObject: "${output.globalObject}" globalObject: "${output!!.globalObject}"
}; };
""".trimIndent() """.trimIndent()
@@ -382,13 +382,13 @@ data class KotlinWebpackConfig(
} }
private fun Appendable.appendResolveModules() { private fun Appendable.appendResolveModules() {
if (!resolveFromModulesFirst || entry == null || entry.parent == null) return if (!resolveFromModulesFirst || entry == null || entry!!.parent == null) return
//language=JavaScript 1.8 //language=JavaScript 1.8
appendln( appendln(
""" """
// resolve modules // resolve modules
config.resolve.modules.unshift(${entry.parent.jsQuoted()}) config.resolve.modules.unshift(${entry!!.parent.jsQuoted()})
""".trimIndent() """.trimIndent()
) )
@@ -409,7 +409,7 @@ data class KotlinWebpackConfig(
let msg = `${"$"}{Math.trunc(p / 10)}${"$"}{Math.trunc(p % 10)}% ${"$"}{message} ${"$"}{args.join(' ')}`; let msg = `${"$"}{Math.trunc(p / 10)}${"$"}{Math.trunc(p % 10)}% ${"$"}{message} ${"$"}{args.join(' ')}`;
${ ${
if (progressReporterPathFilter == null) "" else """ if (progressReporterPathFilter == null) "" else """
msg = msg.replace(new RegExp(${progressReporterPathFilter.jsQuoted()}, 'g'), ''); msg = msg.replace(new RegExp(${progressReporterPathFilter!!.jsQuoted()}, 'g'), '');
""".trimIndent() """.trimIndent()
}; };
console.log(msg); console.log(msg);