[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.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 {
@@ -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<KotlinWebpack.() -> Unit> = mutableListOf()
private val commonRunConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val webpackTaskConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val runTaskConfigurations: MutableList<KotlinWebpack.() -> 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
)
}
@@ -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<KotlinWebpack.() -> Unit> = mutableListOf()
private val commonRunConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val webpackTaskConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val runTaskConfigurations: MutableList<KotlinWebpack.() -> Unit> = mutableListOf()
private val dceConfigurations: MutableList<KotlinJsDce.() -> 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
)
}
@@ -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
@@ -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
@@ -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<RequiredKotlinJsDependency>().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);