When building NodeJS applications you may import stuff from Maven. When doing so and using the browser target, webpack helps you by packing all in a single file and no more issues.
Would that be possible for NodeJS as well? If not, why and how to overcome the issue?
Iād also like to point out that documentation around tasks that builds node modules packages out of a Kotlin/JS project is very lacking and having to scout each and every Gradle tasks of the Kotlin/JS plugin is really frustrating!
I managed with a custom tasks to generate the configuration:
open class GenerateWebpackConfig : DefaultTask() {
enum class Target {
NODE, BROWSER
}
private val template = """
module.exports = [{
name: 'server',
entry: '%%%ENTRY%%%',
target: '%%%MODE%%%', // <-- importat part!
output: {
path: '%%%OUTPUT_PATH%%%',
filename: '%%%OUTPUT_NAME%%%',
},
resolve: {
modules: [%%%MODULES_FOLDER%%%]
}
}];
""".trimIndent()
@get:InputFile
var entryFile by project.objects.property<File>()
@get:Input
var target: Target = Target.NODE
@get:Input
var outputBundleFolder by project.objects.property<String>()
@get:Input
var outputBundleName by project.objects.property<String>()
@get:InputFiles
var modulesFolder = project.objects.listProperty(File::class)
@get:OutputFile
var outputConfig by project.objects.property<File>()
init {
with(project) {
outputBundleFolder = file("$buildDir\\bundle").absolutePath
outputBundleName = "bundle.js"
modulesFolder.set(listOf(file("node_modules")))
outputConfig = file("$buildDir/config/webpack.config.js")
}
}
@TaskAction
fun buildFile() {
outputConfig.writeText(
template.replace("%%%ENTRY%%%", entryFile.absolutePath.replace("\\", "\\\\"))
.replace("%%%MODE%%%", target.toString().toLowerCase())
.replace("%%%OUTPUT_PATH%%%", outputBundleFolder.replace("\\", "\\\\"))
.replace("%%%OUTPUT_NAME%%%", outputBundleName)
.replace(
"%%%MODULES_FOLDER%%%",
modulesFolder.get().joinToString(",") { "'${it.absolutePath.replace("\\", "\\\\")}'" }
)
)
}
}
And the buildscript:
import com.github.gradle.node.task.NodeTask
import it.belabs.gradle.tasks.GenerateWebpackConfig
import it.belabs.gradle.tasks.GenerateWebpackConfig.Target.NODE
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinPackageJsonTask
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.RootPackageJsonTask
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
plugins {
kotlin("js")
id("com.github.node-gradle.node")
}
kotlin {
js {
useCommonJs()
nodejs()
binaries.executable()
}
}
val compileKotlinJs by tasks.getting(Kotlin2JsCompile::class)
val packageJson by tasks.getting(KotlinPackageJsonTask::class)
val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class)
val generateWebpackConfig by tasks.creating(GenerateWebpackConfig::class) {
target = NODE
entryFile = compileKotlinJs.outputFile
modulesFolder.set(listOf(File(rootPackageJson.rootPackageJson.parentFile, "node_modules")))
}
val packAction by tasks.creating(NodeTask::class) {
group = "distribution"
dependsOn(generateWebpackConfig, compileKotlinJs, rootPackageJson, tasks.npmInstall)
script.set(file("node_modules/webpack-cli/bin/cli.js"))
args.set(listOf("-c", generateWebpackConfig.outputConfig.absolutePath))
}
the tasks that generated the configurations are compileKotlinJs, packageJson and the rootProject task rootPackageJson. I was able to install webpack and webpack-cli locally with a local package.json using the Node Gradle Plugin and invoking it via a task. Gosh the JS tooling ecosystem is messed up!