Hello Guys, how do you build you docker images for...
# javascript
t
Hello Guys, how do you build you docker images for node.js?
b
FROM nodejs WORKDIR /app COPY build/distribution . ENTRYPOINT node my-app.js
t
@Big Chungus Thanks, I don't see *.js in build/distribution? I need to specify it in webpackTask explicitely to put it there or should it be default? (My gradle build is bit unconventional (node+browser))
b
Do you have binaries.executable() in your config?
t
Copy code
js("node", IR) {
        nodejs { }
        compilations["main"].defaultSourceSet.dependsOn(js(IR).compilations["main"].defaultSourceSet)
        configurations.all { if(name == compilations["main"].apiConfigurationName + "Elements") attributes.attribute(jsPlatformType, "node") }
        configurations.all { if(name == "nodeRuntimeElements") attributes.attribute(jsPlatformType, "node") }
        binaries.executable()
    }
I mean, yes : )
b
Then run ./gradew build and it should be there
Otherwise have a look at gradle tasks and look for something like distZip or assemble distribution
t
It's not. "main.js" comes from
js("browser", IR)
which has explicit webpackTask
Copy code
js("browser", IR) {
        browser {
            commonWebpackConfig {
                cssSupport.enabled = true
            }
            runTask {
                devServer = KotlinWebpackConfig.DevServer(
                    port = 3001,
                    open = false,
                    static = mutableListOf(
                        project.projectDir.absolutePath + "/src/jsMain/resources",
                    ),
                    proxy = mutableMapOf(
                        "/" to mapOf("target" to "<http://localhost:3000>", "ws" to true),
                    )
                )
                outputFileName = "main.js"
            }
            webpackTask {
                sourceMaps = true
                destinationDirectory = project.buildDir.resolve("distributions/js")
                outputFileName = "main.js"
            }
        }
        compilations["main"].defaultSourceSet.dependsOn(js(IR).compilations["main"].defaultSourceSet)
        configurations.all { if(name == compilations["main"].apiConfigurationName + "Elements") attributes.attribute(jsPlatformType, "browser") }
        configurations.all { if(name == "browserRuntimeElements") attributes.attribute(jsPlatformType, "browser") }
        binaries.executable()
    }
b
I see. Then you can use pack task from my github.com/mpetuska/npm-publish plugin
Or just assemble if you don't want tarballs
Looks like nodejs is still lacking when compared with browser
Just apply the plugin and run gradlew pack (or assemble). Then look for results in build/publications/npm/node
t
Do you know what task should assemble the binary by default?
If I publish to npm, than I need to somehow build Dockerfile from npm registry... but probably I can find some guide online.
b
You don't need to publish with the plugin
You can just use assembled publication locally and copy it in your docker image
t
I respect your contribution to open-source, but I still want to make sure that I need an additional unofficial plugin, before I add one ; )
b
Well looks like nodejs flavour is missing distribution support. For browser flavour it's enough to just run gradlew build and get all files in build/distribution. If you don't want extra plugin, then you can just collect outputs of processResources, publicPackageJson and syncSources tasks yourself
t
"Well looks like nodejs flavour is missing distribution support" -Than, I might use your plaugin after all... ; )
b
Let me know if you still face issues
t
@Big Chungus Thanks, for now I am enjoying Sunday : )
@Big Chungus I don't think I can configure your plugin properly when targeting both node and browser https://github.com/mpetuska/npm-publish/blob/331369462253c1fe63fbe1fb946978ddb6757f3e/src/main/kotlin/dsl/NpmPublication.kt#L93 . Maybe if I create separate module for node packaging...
b
Yeah, you need to target only one of them and use binaries.library() instead of executable
Then in your docker image, npm install before ENTRYPOINT to pull in npm dependencies if any
To be clear, that's the limitation of IR backend.
No idea why, tho
t
Ahh... doesn't work.
Copy code
> Cannot resolve project dependency project ':package' -> project ':app'.Dependency to project with multiple js compilation not supported yet.
I guess I'll have to write my own packaging.
b
Shame... Can't wait until IR is stable to iron these quirks out
Tbh, you can just use browser flavour and run its distribution with nodejs as long as you don't use any of the browser's apis
Not ideal, but easy and works most of the time
t
K. let's try it : )
Unfortunately dependency resolution fails, when I try to target browser instead of node.
b
Ok, I'm out of ideas then. Write your own custom task to collect all relevant outputs
Although if you use binaries.executable() you only need productionExecutable and processResources outputs
Which is fairly straightforward to collect and manage
t
Is there any nicer way to access path "build/compileSync/main/productionExecutable/kotlin", than hardcodeing it?
b
Have you tried passing productionExecutable.outputs to copy spec?
I.e. using gradle built in tooling for copying outputs between tasks
t
Trying to figure out, how to access productionExecutable...
b
val jsProductionExecutable by tasks.getting
Or whatever the task is named for you
You can even pass the task itself to copy spec
t
Ok, thanks