Vampire
10/20/2024, 6:19 PMplugins {
kotlin("multiplatform") version "2.0.21"
}
repositories {
mavenCentral()
}
kotlin {
js {
useEsModules()
binaries.executable()
nodejs()
}
sourceSets {
jsMain {
dependencies {
implementation(dependencies.platform("io.ktor:ktor-bom:3.0.0"))
implementation("io.ktor:ktor-client-core")
implementation("io.ktor:ktor-client-js")
}
}
}
}
and Main.kt
import io.ktor.client.HttpClient
import io.ktor.client.engine.js.Js
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import io.ktor.http.isSuccess
suspend fun main() {
runCatching {
val client = HttpClient(Js)
val response = client.get("<https://echo.free.beeceptor.com/api/GetFiles>")
if (response.status.isSuccess()) {
println("Request:\n${response.bodyAsText()}")
} else {
println("Could not get response (statusCode: ${response.status.value} / statusMessage: ${response.status.description})")
}
}.onFailure {
it.printStackTrace()
}
}
but when I execute the task :jsNodeProductionRun
, I get
ReferenceError: require is not defined
at eval (eval at AbortController_0 (file:///D:/mnt/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt:44:33), <anonymous>:1:1)
at AbortController_0 (file:///D:/mnt/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt:44:33)
at $executeCOROUTINE$20.protoOf.a8 (file:///D:/mnt/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt:45:26)
at JsClientEngine.protoOf.h22 (file:///D:/Sourcecode/other/others/showcase/build/js/packages/showcase/kotlin/ktor-ktor-client-ktor-client-core.mjs:6716:14)
at HttpClientEngine$executeWithinCallContext$slambda.protoOf.a8 (file:///D:/mnt/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/common/src/io/ktor/client/engine/HttpClientEngine.kt:100:13)
at HttpClientEngine$executeWithinCallContext$slambda.protoOf.g22 (file:///D:/Sourcecode/other/others/showcase/build/js/packages/showcase/kotlin/ktor-ktor-client-ktor-client-core.mjs:1404:14)
at l (file:///D:/Sourcecode/other/others/showcase/build/js/packages/showcase/kotlin/ktor-ktor-client-ktor-client-core.mjs:1452:14)
at _no_name_provided__qut3iv_0.protoOf.a8 (file:///D:/Sourcecode/other/others/showcase/build/js/packages/showcase/kotlin/js/src/kotlin/coroutines/intrinsics/IntrinsicsJs.kt:179:40)
at _no_name_provided__qut3iv_0.protoOf.z7 (file:///D:/Sourcecode/other/others/showcase/build/js/packages/showcase/kotlin/src/kotlin/util/Standard.kt:50:44)
at _no_name_provided__qut3iv_0.protoOf.d8 (file:///D:/Sourcecode/other/others/showcase/build/js/packages/showcase/kotlin/kotlin-kotlin-stdlib.mjs:4266:15)
If I change from useEsModules()
to useCommonJs()
in the build script it works, but that is not an option in the actual project.Aleksei Tirman [JB]
10/21/2024, 7:31 AMturansky
10/21/2024, 8:12 AMVampire
10/21/2024, 11:06 AMcompilerOptions.target = "es2015"
as mentioned in that linked ticket, that unfortunately does not change anything, I just tried it.turansky
10/21/2024, 11:24 AMrequire
calls and just use classes in compiled JS files.turansky
10/21/2024, 11:24 AMVampire
10/22/2024, 4:25 PMpill
?
I tried with
tasks.withType<IncrementalSyncTask>().configureEach {
doLast {
outputs
.files
.asFileTree
.filter { it.name == "ktor-ktor-client-ktor-client-core.mjs" }
.forEach {
it
.readText()
.replace("var controller = eval('require')('abort-controller');", "")
.replace("tmp = new controller();", "tmp = new AbortController();")
.replace("jsRequireNodeFetch()(", "fetch(")
.apply(it::writeText)
}
}
}
but there is probably something wrong with it.
It bypasses the "require" errors, but then complains that "this.a2w_1.on is not a function" which is the body.on
calls in NodeFetch.kt
of ktor.turansky
10/22/2024, 4:36 PMreplace("eval('require')('abort-controller');", "globalThis.AbortController")
turansky
10/22/2024, 4:37 PMVampire
10/22/2024, 4:48 PMit
.readText()
.replace("eval('require')('abort-controller')", "globalThis.AbortController")
.replace("eval('require')('node-fetch')", "globalThis.fetch")
.apply(it::writeText)
which gives the same problem from the last line of the my last commentturansky
10/22/2024, 10:35 PMVampire
10/23/2024, 2:41 AMVampire
10/23/2024, 2:41 AMVampire
10/23/2024, 2:49 AMfetch
and thus the body in the response does not have the expected method or something like thatVampire
10/23/2024, 2:52 AMws
require and the crypto
require.
Those are not in my replacements because I didn't hit them so far and just replaced what I got an error about. πturansky
10/23/2024, 9:10 AMVampire
10/23/2024, 10:55 AMturansky
10/23/2024, 3:50 PMVampire
10/23/2024, 4:07 PMturansky
10/23/2024, 8:37 PMJust that your PR has the exact same problem I described.PR updated π
Vampire
10/23/2024, 9:14 PMVampire
10/23/2024, 9:20 PMncc
the result produces "Error: Cannot find module 'abort-controller'".
It only worked when using the compile result before sending through ncc
. πturansky
10/23/2024, 9:43 PMturansky
10/23/2024, 9:45 PMI'd expect that it was intentional that on node different code was used than in the browser. π€·ββοΈ
fetch
exists in Node since Node 18.
JS also want be "multiplatform" πVampire
10/23/2024, 11:19 PMeval('require')(
by require(
in the compile result before sending it through ncc, that allows it to pack properly and it seems to work so far. :-)Vampire
10/24/2024, 4:41 PM.replace("eval('require')('abort-controller')", "globalThis.AbortController")
.replace("eval('require')('node-fetch')", "globalThis.fetch")
.replace("function readBodyNode(", "function _readBodyNode(")
.replace(" readBodyNode(", " readBodyBrowser(")
as I'm currently not hitting the other two `require`s. π