KT-52637 SCSS support
^KT-52637 fixed
This commit is contained in:
committed by
teamcity
parent
b42cbf6650
commit
6cf085aafb
+2
-2
@@ -92,7 +92,7 @@ class BuildReportsIT : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@DisplayName("")
|
||||
@DisplayName("smoke")
|
||||
@GradleTest
|
||||
fun testSingleBuildMetricsFileSmoke(gradleVersion: GradleVersion) {
|
||||
project("simpleProject", gradleVersion) {
|
||||
@@ -109,4 +109,4 @@ class BuildReportsIT : KGPBaseTest() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.gradle.api.logging.configuration.WarningMode
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
|
||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class AbstractJsConfigurationCacheIT(protected val irBackend: Boolean) : KGPBaseTest() {
|
||||
private val defaultJsOptions = BuildOptions.JsOptions(
|
||||
@@ -93,4 +95,4 @@ abstract class AbstractJsConfigurationCacheIT(protected val irBackend: Boolean)
|
||||
class JsConfigurationCacheIT : AbstractJsConfigurationCacheIT(irBackend = false)
|
||||
|
||||
@JsGradlePluginTests
|
||||
class JsIrConfigurationCacheIT : AbstractJsConfigurationCacheIT(irBackend = true)
|
||||
class JsIrConfigurationCacheIT : AbstractJsConfigurationCacheIT(irBackend = true)
|
||||
|
||||
+9
-1
@@ -74,7 +74,12 @@ fun KGPBaseTest.project(
|
||||
localRepoDir?.let { testProject.configureLocalRepository(localRepoDir) }
|
||||
if (buildJdk != null) testProject.setupNonDefaultJdk(buildJdk)
|
||||
|
||||
testProject.test()
|
||||
runCatching {
|
||||
testProject.test()
|
||||
}.onFailure {
|
||||
// A convenient place to place a breakpoint to be able to inspect project output files
|
||||
throw it
|
||||
}
|
||||
return testProject
|
||||
}
|
||||
|
||||
@@ -411,6 +416,7 @@ internal fun Path.addPluginManagementToSettings() {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
Files.exists(settingsGradleKts) -> settingsGradleKts.modify {
|
||||
if (!it.contains("pluginManagement {")) {
|
||||
"""
|
||||
@@ -422,6 +428,7 @@ internal fun Path.addPluginManagementToSettings() {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
else -> settingsGradle.toFile().writeText(DEFAULT_GROOVY_SETTINGS_FILE)
|
||||
}
|
||||
|
||||
@@ -519,6 +526,7 @@ internal fun Path.enableCacheRedirector() {
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
"build.gradle.kts" -> {
|
||||
it.appendText(
|
||||
"""
|
||||
|
||||
+7
-2
@@ -12,7 +12,12 @@ kotlin {
|
||||
js(IR) {
|
||||
browser {
|
||||
commonWebpackConfig {
|
||||
cssSupport.enabled = true
|
||||
cssSupport {
|
||||
enabled.set(true)
|
||||
}
|
||||
scssSupport {
|
||||
enabled.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,4 +25,4 @@ kotlin {
|
||||
|
||||
dependencies {
|
||||
"jsMainImplementation"(npm("decamelize", "4.0.0", generateExternals = true))
|
||||
}
|
||||
}
|
||||
|
||||
+23
-3
@@ -1,3 +1,6 @@
|
||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||
import javax.inject.Inject
|
||||
|
||||
plugins {
|
||||
kotlin("js")
|
||||
}
|
||||
@@ -9,18 +12,35 @@ dependencies {
|
||||
testImplementation(kotlin("test-js"))
|
||||
}
|
||||
|
||||
abstract class CustomWebpackRule
|
||||
@javax.inject.Inject
|
||||
constructor(name: String) : org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackRule(name) {
|
||||
init {
|
||||
test.set("none")
|
||||
}
|
||||
override fun loaders() = listOf<org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackRule.Loader>()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
target {
|
||||
browser {
|
||||
webpackTask {
|
||||
cssSupport.enabled = true
|
||||
cssSupport {
|
||||
enabled.set(true)
|
||||
}
|
||||
scssSupport {
|
||||
enabled.set(true)
|
||||
}
|
||||
rules {
|
||||
rule<CustomWebpackRule>("custom")
|
||||
}
|
||||
}
|
||||
testTask {
|
||||
useKarma {
|
||||
useChromeHeadless()
|
||||
}
|
||||
enabled = false // Task is disabled because it requires browser to be installed. That may be a problem on CI.
|
||||
// Disabled but configured task allows us to check at least a part of configuration cache correctness.
|
||||
// Disabled but configured task allows us to check at least a part of configuration cache correctness.
|
||||
}
|
||||
}
|
||||
binaries.executable()
|
||||
@@ -31,4 +51,4 @@ kotlin {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,4 @@ listOf(generateNpmVersions).forEach {
|
||||
"org.jetbrains.kotlin.generators.gradle.targets.js.outputSourceRoot",
|
||||
project(":kotlin-gradle-plugin").projectDir.resolve("src/common/kotlin").absolutePath
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -19,6 +19,8 @@ val npmPackages = listOf(
|
||||
NpmPackage("source-map-support"),
|
||||
NpmPackage("css-loader"),
|
||||
NpmPackage("style-loader"),
|
||||
NpmPackage("sass-loader"),
|
||||
NpmPackage("sass"),
|
||||
NpmPackage("to-string-loader"),
|
||||
NpmPackage("mini-css-extract-plugin"),
|
||||
NpmPackage("mocha"),
|
||||
@@ -40,4 +42,4 @@ data class NpmPackage(
|
||||
val name: String,
|
||||
val version: String? = null,
|
||||
val displayName: String = name
|
||||
)
|
||||
)
|
||||
|
||||
+2
@@ -25,6 +25,8 @@ class NpmVersions : Serializable {
|
||||
val sourceMapSupport = NpmPackageVersion("source-map-support", "0.5.21")
|
||||
val cssLoader = NpmPackageVersion("css-loader", "6.7.1")
|
||||
val styleLoader = NpmPackageVersion("style-loader", "3.3.1")
|
||||
val sassLoader = NpmPackageVersion("sass-loader", "13.0.0")
|
||||
val sass = NpmPackageVersion("sass", "1.52.3")
|
||||
val toStringLoader = NpmPackageVersion("to-string-loader", "1.2.0")
|
||||
val miniCssExtractPlugin = NpmPackageVersion("mini-css-extract-plugin", "2.6.1")
|
||||
val mocha = NpmPackageVersion("mocha", "10.0.0")
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.dsl
|
||||
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackRule
|
||||
|
||||
class KotlinWebpackRulesContainer(
|
||||
container: ExtensiblePolymorphicDomainObjectContainer<KotlinWebpackRule>,
|
||||
private val objectFactory: ObjectFactory,
|
||||
) : ExtensiblePolymorphicDomainObjectContainer<KotlinWebpackRule> by container {
|
||||
inline fun <reified T : KotlinWebpackRule> rule(name: String, config: Action<T> = Action {}) {
|
||||
rule(T::class.java, name, config)
|
||||
}
|
||||
|
||||
fun <T : KotlinWebpackRule> rule(type: Class<T>, name: String, config: Action<T> = Action {}) {
|
||||
add(objectFactory.newInstance(type, name).also(config::execute))
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.dsl
|
||||
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.tasks.Nested
|
||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackCssRule
|
||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackRule
|
||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackScssRule
|
||||
import org.jetbrains.kotlin.gradle.utils.newInstance
|
||||
|
||||
interface WebpackRulesDsl {
|
||||
@get:Nested
|
||||
val rules: KotlinWebpackRulesContainer
|
||||
|
||||
fun rules(action: Action<KotlinWebpackRulesContainer>) {
|
||||
action.execute(rules)
|
||||
}
|
||||
|
||||
fun cssSupport(action: Action<KotlinWebpackCssRule>) {
|
||||
val rule = rules.maybeCreate("css", KotlinWebpackCssRule::class.java)
|
||||
action.execute(rule)
|
||||
}
|
||||
|
||||
fun scssSupport(action: Action<KotlinWebpackScssRule>) {
|
||||
val rule = rules.maybeCreate("scss", KotlinWebpackScssRule::class.java)
|
||||
action.execute(rule)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private inline fun <reified T : KotlinWebpackRule> ObjectFactory.bindTo(
|
||||
container: ExtensiblePolymorphicDomainObjectContainer<KotlinWebpackRule>
|
||||
) = container.registerFactory(T::class.java) { newInstance<T>(it) }
|
||||
|
||||
fun ObjectFactory.webpackRulesContainer(): KotlinWebpackRulesContainer {
|
||||
val delegate = polymorphicDomainObjectContainer(KotlinWebpackRule::class.java).also {
|
||||
bindTo<KotlinWebpackCssRule>(it)
|
||||
bindTo<KotlinWebpackScssRule>(it)
|
||||
}
|
||||
return KotlinWebpackRulesContainer(delegate, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecuti
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
|
||||
import org.jetbrains.kotlin.gradle.targets.js.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.WebpackRulesDsl.Companion.webpackRulesContainer
|
||||
import org.jetbrains.kotlin.gradle.targets.js.internal.parseNodeJsStackTraceAsJvm
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||
@@ -40,11 +41,11 @@ class KotlinKarma(
|
||||
@Transient override val compilation: KotlinJsCompilation,
|
||||
private val services: () -> ServiceRegistry,
|
||||
private val basePath: String
|
||||
) :
|
||||
KotlinJsTestFramework {
|
||||
) : KotlinJsTestFramework {
|
||||
@Transient
|
||||
private val project: Project = compilation.target.project
|
||||
private val npmProject = compilation.npmProject
|
||||
|
||||
@Transient
|
||||
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val nodeRootPackageDir by lazy { nodeJs.rootPackageDir }
|
||||
@@ -80,7 +81,8 @@ class KotlinKarma(
|
||||
export = false,
|
||||
progressReporter = true,
|
||||
progressReporterPathFilter = nodeRootPackageDir.absolutePath,
|
||||
webpackMajorVersion = webpackMajorVersion
|
||||
webpackMajorVersion = webpackMajorVersion,
|
||||
rules = project.objects.webpackRulesContainer(),
|
||||
)
|
||||
|
||||
init {
|
||||
|
||||
+11
-6
@@ -29,6 +29,9 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.distsDirectory
|
||||
import org.jetbrains.kotlin.gradle.report.BuildMetricsReporterService
|
||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWebpackRulesContainer
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.WebpackRulesDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.WebpackRulesDsl.Companion.webpackRulesContainer
|
||||
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||
@@ -47,7 +50,7 @@ constructor(
|
||||
@Transient
|
||||
override val compilation: KotlinJsCompilation,
|
||||
objects: ObjectFactory
|
||||
) : DefaultTask(), RequiresNpmDependencies {
|
||||
) : DefaultTask(), RequiresNpmDependencies, WebpackRulesDsl {
|
||||
@Transient
|
||||
private val nodeJs = NodeJsRootPlugin.apply(project.rootProject)
|
||||
private val versions = nodeJs.versions
|
||||
@@ -62,6 +65,9 @@ constructor(
|
||||
open val fileResolver: FileResolver
|
||||
get() = injected
|
||||
|
||||
override val rules: KotlinWebpackRulesContainer =
|
||||
project.objects.webpackRulesContainer()
|
||||
|
||||
@get:Inject
|
||||
open val execHandleFactory: ExecHandleFactory
|
||||
get() = injected
|
||||
@@ -204,9 +210,6 @@ constructor(
|
||||
@Input
|
||||
var sourceMaps: Boolean = true
|
||||
|
||||
@Nested
|
||||
val cssSupport: KotlinWebpackCssSupport = KotlinWebpackCssSupport()
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
var devServer: KotlinWebpackConfig.DevServer? = null
|
||||
@@ -219,7 +222,9 @@ constructor(
|
||||
var generateConfigOnly: Boolean = false
|
||||
|
||||
@Nested
|
||||
val synthConfig = KotlinWebpackConfig()
|
||||
val synthConfig = KotlinWebpackConfig(
|
||||
rules = project.objects.webpackRulesContainer(),
|
||||
)
|
||||
|
||||
@Input
|
||||
val webpackMajorVersion = PropertiesProvider(project).webpackMajorVersion
|
||||
@@ -249,7 +254,7 @@ constructor(
|
||||
outputFileName = outputFileName,
|
||||
configDirectory = configDirectory,
|
||||
bundleAnalyzerReportDir = if (!forNpmDependencies && report) reportDir else null,
|
||||
cssSupport = cssSupport,
|
||||
rules = rules,
|
||||
devServer = devServer,
|
||||
devtool = devtool,
|
||||
sourceMaps = sourceMaps,
|
||||
|
||||
+14
-131
@@ -8,6 +8,8 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.js.webpack
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.Nested
|
||||
@@ -15,10 +17,9 @@ import org.gradle.api.tasks.Optional
|
||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
import org.jetbrains.kotlin.gradle.targets.js.appendConfigsFromDir
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinWebpackRulesContainer
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.WebpackRulesDsl
|
||||
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 org.jetbrains.kotlin.gradle.utils.appendLine
|
||||
import java.io.File
|
||||
@@ -51,7 +52,7 @@ data class KotlinWebpackConfig(
|
||||
@Input
|
||||
var experiments: MutableSet<String> = mutableSetOf(),
|
||||
@Nested
|
||||
var cssSupport: KotlinWebpackCssSupport = KotlinWebpackCssSupport(),
|
||||
override val rules: KotlinWebpackRulesContainer,
|
||||
@Input
|
||||
@Optional
|
||||
var devtool: String? = WebpackDevtool.EVAL_SOURCE_MAP,
|
||||
@@ -70,7 +71,7 @@ data class KotlinWebpackConfig(
|
||||
var resolveFromModulesFirst: Boolean = false,
|
||||
@Input
|
||||
val webpackMajorVersion: WebpackMajorVersion = WebpackMajorVersion.V5
|
||||
) {
|
||||
) : WebpackRulesDsl {
|
||||
@get:Input
|
||||
@get:Optional
|
||||
val entryInput: String?
|
||||
@@ -135,18 +136,11 @@ data class KotlinWebpackConfig(
|
||||
)
|
||||
}
|
||||
|
||||
if (!cssSupport.enabled || cssSupport.rules.isEmpty()) return@also
|
||||
|
||||
it.add(versions.cssLoader)
|
||||
cssSupport.rules.forEach { rule ->
|
||||
when (rule.mode) {
|
||||
EXTRACT -> it.add(versions.miniCssExtractPlugin)
|
||||
INLINE -> it.add(versions.styleLoader)
|
||||
IMPORT -> it.add(versions.toStringLoader)
|
||||
else -> cssError()
|
||||
rules.forEach { rule ->
|
||||
if (rule.active) {
|
||||
it.addAll(rule.dependencies(versions))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class Mode(val code: String) {
|
||||
@@ -215,7 +209,11 @@ data class KotlinWebpackConfig(
|
||||
appendDevServer()
|
||||
appendReport()
|
||||
appendProgressReporter()
|
||||
appendCssSupport()
|
||||
rules.forEach { rule ->
|
||||
if (rule.active) {
|
||||
with(rule) { appendToWebpackConfig() }
|
||||
}
|
||||
}
|
||||
appendErrorPlugin()
|
||||
appendFromConfigDir()
|
||||
appendEvaluatedFileReport()
|
||||
@@ -363,109 +361,6 @@ data class KotlinWebpackConfig(
|
||||
)
|
||||
}
|
||||
|
||||
private fun Appendable.appendCssSupport() {
|
||||
if (!cssSupport.enabled || cssSupport.rules.isEmpty())
|
||||
return
|
||||
|
||||
appendLine(
|
||||
"""
|
||||
// css settings
|
||||
;(function(config) {
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val extractedCss =
|
||||
"""
|
||||
| const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
| use.unshift({
|
||||
| loader: MiniCssExtractPlugin.loader,
|
||||
| options: {}
|
||||
| })
|
||||
| config.plugins.push(new MiniCssExtractPlugin())
|
||||
""".trimMargin()
|
||||
|
||||
val inlinedCss =
|
||||
"""
|
||||
| use.unshift({
|
||||
| loader: 'style-loader',
|
||||
| options: {}
|
||||
| })
|
||||
|
|
||||
""".trimMargin()
|
||||
|
||||
val importedCss =
|
||||
"""
|
||||
| use.unshift({
|
||||
| loader: 'to-string-loader',
|
||||
| options: {}
|
||||
| })
|
||||
|
|
||||
""".trimMargin()
|
||||
|
||||
cssSupport.rules.forEach { rule ->
|
||||
appendLine(
|
||||
"""
|
||||
| ;(function(config) {
|
||||
""".trimMargin()
|
||||
)
|
||||
appendLine(
|
||||
"""
|
||||
| const use = [
|
||||
| {
|
||||
| loader: 'css-loader',
|
||||
| options: {},
|
||||
| }
|
||||
| ]
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
when (rule.mode) {
|
||||
EXTRACT -> appendLine(extractedCss)
|
||||
INLINE -> appendLine(inlinedCss)
|
||||
IMPORT -> appendLine(importedCss)
|
||||
else -> cssError()
|
||||
}
|
||||
|
||||
val excluded = rule.exclude.let {
|
||||
if (it.isNotEmpty()) {
|
||||
"[${it.joinToString()}]"
|
||||
} else null
|
||||
}
|
||||
|
||||
val included = rule.include.let {
|
||||
if (it.isNotEmpty()) {
|
||||
"[${it.joinToString()}]"
|
||||
} else null
|
||||
}
|
||||
|
||||
appendLine(
|
||||
"""
|
||||
| config.module.rules.push({
|
||||
| test: /\.css${'$'}/,
|
||||
| use: use,
|
||||
| ${excluded?.let { "exclude: $it," } ?: ""}
|
||||
| ${included?.let { "include: $it" } ?: ""}
|
||||
| })
|
||||
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
appendLine(
|
||||
"""
|
||||
| })(config);
|
||||
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
|
||||
appendLine(
|
||||
"""
|
||||
})(config);
|
||||
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun Appendable.appendErrorPlugin() {
|
||||
//language=ES6
|
||||
appendLine(
|
||||
@@ -525,18 +420,6 @@ data class KotlinWebpackConfig(
|
||||
)
|
||||
}
|
||||
|
||||
private fun cssError() {
|
||||
throw IllegalStateException(
|
||||
"""
|
||||
Possible values for cssSupport.mode:
|
||||
- EXTRACT
|
||||
- INLINE
|
||||
- IMPORT
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun json(obj: Any) = StringWriter().also {
|
||||
GsonBuilder().setPrettyPrinting().create().toJson(obj, it)
|
||||
}.toString()
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
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 javax.inject.Inject
|
||||
|
||||
@Deprecated(
|
||||
message = "Renamed to KotlinWebpackCssRule", replaceWith = ReplaceWith(
|
||||
expression = "KotlinWebpackCssRule",
|
||||
imports = arrayOf("org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackCssRule")
|
||||
)
|
||||
)
|
||||
typealias KotlinWebpackCssSupport = KotlinWebpackCssRule
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
abstract class KotlinWebpackCssRule @Inject constructor(name: String) : KotlinWebpackRule(name) {
|
||||
@get:Input
|
||||
abstract val mode: Property<String>
|
||||
|
||||
init {
|
||||
mode.convention(INLINE)
|
||||
test.convention("/\\.css\$/")
|
||||
}
|
||||
|
||||
override fun validate(): Boolean {
|
||||
if (mode.get() !in arrayOf(EXTRACT, INLINE, IMPORT)) {
|
||||
error(
|
||||
"""
|
||||
Possible values for cssSupport.mode:
|
||||
- EXTRACT
|
||||
- INLINE
|
||||
- IMPORT
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun dependencies(versions: NpmVersions): Collection<RequiredKotlinJsDependency> {
|
||||
return mutableListOf<RequiredKotlinJsDependency>().apply {
|
||||
add(versions.cssLoader)
|
||||
when (mode.get()) {
|
||||
EXTRACT -> add(versions.miniCssExtractPlugin)
|
||||
INLINE -> add(versions.styleLoader)
|
||||
IMPORT -> add(versions.toStringLoader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun loaders(): List<Loader> = when (mode.get()) {
|
||||
EXTRACT -> listOf(
|
||||
Loader(
|
||||
loader = "MiniCssExtractPlugin.loader",
|
||||
prerequisites = listOf(
|
||||
"const MiniCssExtractPlugin = require('mini-css-extract-plugin');",
|
||||
"config.plugins.push(new MiniCssExtractPlugin())"
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
INLINE -> listOf(Loader(loader = "'style-loader'"))
|
||||
IMPORT -> listOf(Loader(loader = "'to-string-loader'"))
|
||||
else -> listOf()
|
||||
} + Loader(loader = "'css-loader'")
|
||||
}
|
||||
|
||||
object KotlinWebpackCssMode {
|
||||
const val EXTRACT = "extract"
|
||||
const val INLINE = "inline"
|
||||
const val IMPORT = "import"
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.Nested
|
||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackCssMode.INLINE
|
||||
|
||||
data class KotlinWebpackCssSupport(
|
||||
@Input
|
||||
var enabled: Boolean = false,
|
||||
|
||||
@Nested
|
||||
var rules: MutableList<KotlinWebpackCssRule> = mutableListOf(
|
||||
KotlinWebpackCssRule()
|
||||
)
|
||||
) {
|
||||
@get:Internal
|
||||
var mode: String
|
||||
get() =
|
||||
rules
|
||||
.singleOrNull()
|
||||
?.mode ?: singleRuleError()
|
||||
set(value) {
|
||||
rules.singleOrNull()
|
||||
?.let {
|
||||
it.mode = value
|
||||
} ?: singleRuleError()
|
||||
}
|
||||
|
||||
private fun singleRuleError(): Nothing {
|
||||
error("CSS mode shortcut can be applied only with one css rule")
|
||||
}
|
||||
}
|
||||
|
||||
data class KotlinWebpackCssRule(
|
||||
@Input
|
||||
var mode: String = INLINE,
|
||||
|
||||
@Input
|
||||
var include: MutableList<String> = mutableListOf(),
|
||||
|
||||
@Input
|
||||
var exclude: MutableList<String> = mutableListOf()
|
||||
)
|
||||
|
||||
object KotlinWebpackCssMode {
|
||||
const val EXTRACT = "extract"
|
||||
const val INLINE = "inline"
|
||||
const val IMPORT = "import"
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
import com.google.gson.GsonBuilder
|
||||
import org.gradle.api.Named
|
||||
import org.gradle.api.provider.ListProperty
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
import org.jetbrains.kotlin.gradle.utils.appendLine
|
||||
import java.io.StringWriter
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
abstract class KotlinWebpackRule @Inject constructor(private val name: String) : Named {
|
||||
@get:Input
|
||||
abstract val enabled: Property<Boolean>
|
||||
|
||||
/**
|
||||
* Raw rule `test` field value. Needs to be wrapped in quotes when using string notation.
|
||||
*/
|
||||
@get:Input
|
||||
abstract val test: Property<String>
|
||||
|
||||
@get:Input
|
||||
abstract val include: ListProperty<String>
|
||||
|
||||
@get:Input
|
||||
abstract val exclude: ListProperty<String>
|
||||
|
||||
@get:Input
|
||||
protected open val description: String
|
||||
get() = (this::class.simpleName?.removeSuffix("_Decorated") ?: "KotlinWebpackRule") + "[${getName()}]"
|
||||
|
||||
init {
|
||||
enabled.convention(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule state just before it getting applied.
|
||||
* Returning false will skip the rule silently. To terminate the build instead, throw an error.
|
||||
*/
|
||||
open fun validate(): Boolean = true
|
||||
|
||||
/**
|
||||
* Provides a list of required npm dependencies for the rule to function.
|
||||
*/
|
||||
open fun dependencies(versions: NpmVersions): Collection<RequiredKotlinJsDependency> = listOf()
|
||||
|
||||
/**
|
||||
* Provides a loaders sequence to apply to the rule.
|
||||
*/
|
||||
protected abstract fun loaders(): List<Loader>
|
||||
|
||||
@get:Internal
|
||||
internal val active: Boolean get() = enabled.get() && validate()
|
||||
internal fun Appendable.appendToWebpackConfig() {
|
||||
appendLine(
|
||||
"""
|
||||
// $description
|
||||
;(function(config) {
|
||||
""".trimIndent()
|
||||
)
|
||||
val loaders = loaders()
|
||||
loaders.flatMap(Loader::prerequisites).forEach(::appendLine)
|
||||
val use = loaders.joinToString(
|
||||
separator = ",",
|
||||
prefix = "[",
|
||||
postfix = "]",
|
||||
) {
|
||||
"""
|
||||
{
|
||||
loader: ${it.loader},
|
||||
options: ${json(it.options)}
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
appendLine(
|
||||
"""
|
||||
const use = $use
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val excluded = exclude.get().takeIf(List<*>::isNotEmpty)
|
||||
?.joinToString(separator = ",", prefix = "[", postfix = "]") ?: "undefined"
|
||||
val included = include.get().takeIf(List<*>::isNotEmpty)
|
||||
?.joinToString(separator = ",", prefix = "[", postfix = "]") ?: "undefined"
|
||||
appendLine(
|
||||
"""
|
||||
config.module.rules.push({
|
||||
test: ${test.get()},
|
||||
use: use,
|
||||
exclude: $excluded,
|
||||
include: $included,
|
||||
})
|
||||
""".trimIndent()
|
||||
)
|
||||
appendLine(
|
||||
"""
|
||||
})(config);
|
||||
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
protected fun json(obj: Any) = StringWriter().also {
|
||||
GsonBuilder().setPrettyPrinting().create().toJson(obj, it)
|
||||
}.toString()
|
||||
|
||||
@Internal
|
||||
override fun getName(): String = name
|
||||
override fun equals(other: Any?): Boolean = other is KotlinWebpackRule && getName() == other.getName()
|
||||
override fun hashCode(): Int = getName().hashCode()
|
||||
|
||||
data class Loader(
|
||||
/**
|
||||
* Raw `loader` field value. Needs to be wrapped in quotes if using string notation.
|
||||
*/
|
||||
val loader: String,
|
||||
/**
|
||||
* Loader options map if any. Will be converted to json object via Gson.
|
||||
*/
|
||||
val options: Map<String, Any?> = mapOf(),
|
||||
/**
|
||||
* Any prerequisite code to be added before building the loader object.
|
||||
*/
|
||||
val prerequisites: List<String> = listOf(),
|
||||
)
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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
|
||||
|
||||
import org.jetbrains.kotlin.gradle.targets.js.NpmVersions
|
||||
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
abstract class KotlinWebpackScssRule @Inject constructor(name: String) : KotlinWebpackCssRule(name) {
|
||||
init {
|
||||
test.convention("/\\.(scss|sass)\$/")
|
||||
}
|
||||
|
||||
override fun dependencies(versions: NpmVersions): Collection<RequiredKotlinJsDependency> {
|
||||
return super.dependencies(versions) + versions.sass + versions.sassLoader
|
||||
}
|
||||
|
||||
override fun loaders(): List<Loader> {
|
||||
return super.loaders() + Loader(loader = "'sass-loader'")
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -9,4 +9,7 @@ import org.gradle.api.Named
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
|
||||
internal inline fun <reified T : Named> ObjectFactory.named(name: String): T =
|
||||
named(T::class.java, name)
|
||||
named(T::class.java, name)
|
||||
|
||||
internal inline fun <reified T : Named> ObjectFactory.newInstance(vararg args: Any?): T =
|
||||
newInstance(T::class.java, *args)
|
||||
|
||||
Reference in New Issue
Block a user