What's the easiest way to configure Kotlin/JS app ...
# javascript
r
What's the easiest way to configure Kotlin/JS app to generate two webpack bundles - one, standard for the browser and additional one for Node.js. I can do this by manually modifying js file in
webpack.config.d
so probably I can create a custom gradle task to do the same, but is there any other option?
e
Maybe using the compilations concept? You can configure multiple compilations for the same source set, although I've never done it.
👍 1
r
I don't think it will work. The compilation process is the same for both browser and node. The only difference is during bundling and packaging and the problem is there is only one
webpack.config.d
configuration for webpack.
e
The
nodejs
configuration does not use Webpack btw. You can target node by having two compilations with
browser
and changing
webpackTask.configFile
depending on which one is running.
Never done it tho. You'll have to try.
r
Kotlin gradle plugin doesn't like it.
Copy code
Declaring multiple Kotlin Targets of the same type is not recommended
and will become an error in the upcoming Kotlin releases.
e
No no. Not targets, but compilations
Have a look at the docs, there should be a chapter on compilations
e
Yup. The only thing I'm now unsure about is if you can effectively re-use the same source set for an additional compilation.
But what about just passing in a project property and changing behavior based on that? Looks easier.
t
"One compilatition -> two bundles" works fine for simple cases
In simple case you can configure 2 entries (1 for Node, 1 for Browser)
In specific cases you will need second Webpack task - copy of default with modifications
r
Do you know any example projects?
t
I had examples in
kfc-plugins
😞
Probably more flexible (elegant) variant - separate subprojects for bundling.
Copy code
app\ (klib-only? js-only?)
app-browser\ (bundling-only)
    webpack.config.d\
app-node\ (bundling-only)
    webpack.config.d\
e
I'd first check if there is an easier way to do it tho. I mean, passing in a project property like
-Ptarget=node/browser
and then having
Copy code
browser {
  webpackTask {
    configFile = if (isBrowserTarget) ... else ...
  }
}
doesn't look wrong. You'll also have to change the distribution output.
r
I've already tried this way, but it wont allow me to build both bundles at the same time (I want both of them packaged in the destination jar)
e
build both bundles at the same time
I don't think there is a way to have them built at the same time (with the same command)
Is that a necessary prerequisite? You could just add a custom task that depends on two other tasks.
👍 1
1
t
I also expect, that 2 separate Webpack tasks must work fine.
r
I can't find how to change directory where resources (e.g.
index.html
) are copied by
productionWebpack
task. I changed the options in
webpackTask {}
block, and js files are put where I want them, but the resources still go to
dist/js/productionExecutable
.
e
That's something I'd also like to know 😆
r
this partialy works:
Copy code
getByName("jsBrowserProductionExecutableDistributeResources", Copy::class).apply {
            destinationDir = file("build/dist/something/productionExecutable")
        }
copies the files to new dir but still leaves empty
js
directory
If anyone is interested, after hours of struggle I've managed to create a fully working custom production webpack task with this code:
Copy code
val jsBrowserProductionExecutableDistributeResources = tasks.getByName("jsBrowserProductionExecutableDistributeResources", Copy::class)
tasks.register("jsBrowserProductionExecutableDistributeResourcesSSR", Copy::class) {
    from(jsBrowserProductionExecutableDistributeResources.source)
    into("build/dist/js.ssr/productionExecutable")
}
val kotlinWebpackJs = tasks.getByName("jsBrowserProductionWebpack", KotlinWebpack::class)
tasks.register("jsBrowserProductionWebpackSSR", KotlinWebpack::class, kotlinWebpackJs.compilation, project.objects)
tasks.getByName("jsBrowserProductionWebpackSSR", KotlinWebpack::class).apply {
    dependsOn("jsBrowserProductionExecutableDistributeResourcesSSR", "jsProductionExecutableCompileSync")
    mode = KotlinWebpackConfig.Mode.PRODUCTION
    inputFilesDirectory.set(kotlinWebpackJs.inputFilesDirectory.get())
    entryModuleName.set(kotlinWebpackJs.entryModuleName.get())
    esModules.set(kotlinWebpackJs.esModules.get())
    outputDirectory.set(file("build/dist/js.ssr/productionExecutable"))
    mainOutputFileName.set("main.bundle.js")
    this.webpackConfigApplier {
        configDirectory = file("webpack.config.ssr.d")
    }
}
❤️ 3
e
That looks neat. Thank you!