Hi, After updating to kotlin 2.0, I'm getting the ...
# javascript
f
Hi, After updating to kotlin 2.0, I'm getting the following error
Copy code
ReferenceError: require is not defined
at <global>.eval (eval at AbortController(file:///mnt/agent/work/8d547b974a7be21f/ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/compatibility/Utils.kt:46:34), <anonymous>:1)
The project is targeting ES modules
Copy code
useEsModules()
This used to work correctly with 1.9.21 The ktor version is 2.3.11
t
Looks like Ktor issue
h
e
We REALLY need the separation between browser and Node. Like, we can't create a proper library ecosystem without it.
3
t
Like, we can’t create a proper library ecosystem without it.
It’s not true unfortunately
We REALLY need the separation between browser and Node
Problem is wider and 2 targets won’t solve it
need the separation between browser and Node
and worker and service worker and audio service and Deno and Bun and ….
e
Without the minimal separation the codebases will grow full of hacks and workaround
t
It depends on your use cases and solution, which you will choose. Also no separate targets != no code separation.
If you will describe your use case I can highlight possible solutions. Do you publish klib or NPM package? Which bundler do you use?
a
I do agree with @Edoardo Luppi We REALLY need js target separation, and yes, We can't create a proper library ecosystem without it
Problem is wider than two targets, yes. We are willing to start with two and expand to more. Also, Kotlin/Native already demonstrates that we can successfully go beyond two targets
f
Thanks for the replies. • The problem surfaces when running js/node tests (using the default test runner). The problem does not exist when running js/browser. • I didn't had the problem before moving to kotlin 2.0. • Is there a workaround for this? Not clear from https://youtrack.jetbrains.com/issue/KTOR-6158
t
> Is there a workaround for this? Not clear from Yes 🙂
With bundler -
DefinePlugin
Without bundler - Gradle task with replace after compile
f
Were there any changes from 1.9.* to 2.0.0 that can explain this? Perhaps on the way tests are run in node.
e
There are no new changes. Simply the
require
call is hardcoded, and can't work in ESM mode.
f
Thanks. I wonder why it did work on kotlin 1.9.21. Perhaps a difference on how node is being used to run the tests?
h
You use ES modules, which is not available with 1.9.24
t
which is not available with 1.9.24
Available 🙂
ES modules - 1.9 ES classes - 1.9 Coroutines on generators - 2.0
f
@turansky Could you provide a bit more information about the workarounds? Didn't understood you last response, both with or without a bundler.
I'm using ES modules with Kotlin 1.9 and the exact same code does pass the tests on js/node. It only started failing when moving to Kotlin 2.0.
t
1. Webpack
DefinePlugin
can replace
require("abort-handler")
with your custom code. 2. If you don't use bundler - you can do the same replace in
doLast
of task, which produces
*.mjs
file
It only started failing when moving to Kotlin 2.0.
Webpack update can be root cause
f
Thanks. The error is currently occurring in unit tests, using the default config. I don't have any explicit bundling on the tests. How can I get more information on how tests are ran on node, namely: • Is there any bundling occurring before node is called? • How can I see the package.json and the node invocation line being used to run the Mocha (?) tests?
e
As I said earlier, being it's hardcoded you'll have to bundle or invent some other hack.
And being you're executing tests, not all build tasks are executed, some might be missing compared to a production build.
The problem is require should not be hardcoded. Very simple.
However, I'm seeing more and more kotlinx libraries using the
eval("require")
thing, which will obviously make them incompatible with ESM
f
Thanks. Agree. It fails immediately when running tests, for which I don't define any explicit bundling step. I wonder if the way tests are run changed from kotlin 1.9 to kotlin 2.0. If on 1.9 a bundling step was used before running the tests, then the
require
would probably be in scope. If kotlin 2.0 runs the tests without any bundling (namely because node already supports ESM), then the error occurs.
e
You'll have to hack your way into ESM. As I wrote many times the proper fix is NOT LEAKING Node.js declarations in a browser context, so that you don't need to use lazy imports and hardcoded requires. This means a proper split and proper code sharing layer between multiple JS targets. ALL OTHER WAYS ARE HACKS
We might get to it before an asteroid strikes earth