I’m a JavaScript noob trying to create a Kotlin/JS...
# javascript
a
I’m a JavaScript noob trying to create a Kotlin/JS library (generated by emscripten) that works for both NodeJS and browsers. I’m loading a local JS module (using the answer here) I’ve got a test that works for NodeJS, but fails for browsers, on this line.
Copy code
suspend fun main() {
  val libpcre2x = require("jsRequire") as () -> Promise<PcreModule>
  val module = libpcre2x().await()
  module.loaded.await()
  println("pcreModule.version: ${pcreModule.version()}")
  // prints: pcreModule.version: 10.42 2022-12-11
}

@JsName("require")
private external fun jsRequire(value: String): dynamic
Why does
require()
work on NodeJS, but on browsers it fails with ‘Cannot find module’? Is it possible to fix it?
Copy code
Error: Cannot find module 'libpcre2x'
	at <global>.webpackEmptyContext(/projects/rexkt/build/js/packages/rexkt-rexkt-lib-js-browser-test/kotlin|sync:2)
	at protoOf.require_z6w6n0(/projects/rexkt/rexkt-lib/src/jsMain/kotlin/externals/js.kt:8)
	at protoOf.doResume_5yljmg(/projects/rexkt/rexkt-lib/src/jsMain/kotlin/externals/pcre2-wasm.extensions.kt:11)
        ...
I’ve tried using various combinations of
@JsModule
and
@JsNonModule
, but this always returns ‘undefined’
Copy code
@JsModule("libpcre2x")
@JsNonModule
@JsName("default")
//@JsName("libpcre2x")
//@JsName("Module")
external val libpcre2x: dynamic
the
libpcre2x.js
file (generated by emscripten looks like this, so I would expect that I’m able to access the
var libpcre2x
a
Just a stupid question from my side. The library you trying to use is just a file somewhere in your project or it's a package that you published before in npm?
a
it’s not a stupid question, because you guessed right :) I was loading the file using the answer here https://stackoverflow.com/a/68305290/4161471 I actually just found that there’s an option (possibly introduced with Kotlin 1.9? I’m using the RC) to specify a file, and now it works for both NodeJS and browser 🎉
Copy code
kotlin {
  sourceSets {
    jsMain {
      dependencies {
        implementation(npm("libpcre2x", file("local_node_modules/libpcre2x")))
      }
    }
  }
}
🎉 1
👍 1
K 1
a
@Ilya Goncharov [JB] is it possible to include a js file in the final sources, right? By webpack plugin, for example?
Oh, great 🙃
a
next step is to try and get Kotlin/JS to host the wasm file correctly 🤔
Copy code
> Task :rexkt-lib:jsBrowserBrowserTest
Module not found: Error: Can't resolve 'fs' in '/projects/rexkt/build/js/node_modules/libpcre2x/dist'
Module not found: Error: Can't resolve 'path' in '/projects/rexkt/build/js/node_modules/libpcre2x/dist'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
	- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "path": false }
Module not found: Error: Can't resolve 'perf_hooks' in '/projects/rexkt/build/js/node_modules/libpcre2x/dist'
404: /libpcre2x.wasm
404: /libpcre2x.wasm
dev.adamko.rexkt.PcreModuleTest.pcreVersion[jsBrowser, browser, ChromeHeadless114.0.5735.133, MacOS10.15.7] STARTED
dev.adamko.rexkt.PcreModuleTest.pcreVersion[jsBrowser, browser, ChromeHeadless114.0.5735.133, MacOS10.15.7] FAILED
    RuntimeError at /projects/rexkt/build/js/node_modules/libpcre2x/dist/libpcre2x.js:530
a
Yes, the module uses the node specific API, like 'fs' and 'path'.
a
I think it tries to use them, and it’s supposed to fallback to loading it from http://localhost/libpcre2x.wasm - but that 404s. Possibly a webpack thing can fix it?
a
Maybe, but I'm not sure. You could customize the webpack plugin with Kotlin/JS like this: https://kotlinlang.org/docs/js-project-setup.html#webpack-configuration-file
Maybe this discussion also will help you: https://github.com/webpack/webpack/issues/7352