A prerequisites I've been given to use KotlinJS is...
# javascript
e
A prerequisites I've been given to use KotlinJS is the ability to debug from an external tool with sourcemaps. In this case I'm trying to configure a VS Code extension launch configuration. In the Kotlin library side I've configured source map generation. build.gradle.kts:
Copy code
tasks.withType<Kotlin2JsCompile>().configureEach {
  kotlinOptions {
    sourceMap = true
    sourceMapEmbedSources = "always"
    sourceMapNamesPolicy = "fully-qualified-names"
  }
}
The generated source map file is as following:
Copy code
{
  "version": 3,
  "sources": [
    "../../../../../../src/commonMain/kotlin/...",
    "../../../../../../src/jsMain/kotlin/...",
    ...
  ],
  "sourcesContent": [ ... ], // here I can see my source code
  "names": [ ... ],
  "mappings": "..."
}
In the VS Code side I've configured the
launch.json
task file as following:
Copy code
{
  "name": "Run Extension",
  "type": "extensionHost",
  "request": "launch",
  "args": [
    "--extensionDevelopmentPath=${workspaceFolder}"
  ],
  "outFiles": [
    "${workspaceFolder}/dist/**/*.js"
  ],
  "preLaunchTask": "${defaultBuildTask}",
  "sourceMaps": true,
  "pauseForSourceMap": true
}
But yet I can't get source maps to work. I still debug and see the compiled JS.
a
do the source maps work when using dev tools in a browser? Try throwing an exception in the Kotlin/JS code and clicking on the JS stacktrace
e
@Adam S I have to understand how to remote debug a VS Code extension in Chrome first 😆 will give it a go
Or you meant in the VSC DevTools?
a
oh I just meant your library, so enable the executable in build.gradle.kts
Copy code
kotlin {
  js {
    binaries.executable()
  }
}
add a
fun main()
and then run
./gradlew jsBrowserDevelopmentRun
just a basic check to make sure that the source maps work with just Kotlin/JS and a browser, without worrying about external tools
e
Nice trick, thanks. Will let you know in 10 mins
👍 1
I also need to switch from the node target to the browser target tho. Not sure it will compile
a
oh, well, maybe you can also try
jsNodeDevelopmentRun
but I’m not sure how that will work with the source maps…
e
Nope in that case it doesn't open anything. In browser mode it doesn't compile (as I'm using Node stuff)
@Adam S I've created another project for the browser. When I run
jsBrowserDevelopmentRun
it opens a Chrome window with a list of files, is that expected?
a
if you don’t have a file
src/jsMain/resources/index.html
, then yes
e
Yeah I don't have it, you're right. Have you got a sample index.html that imports the compiled JS file?
Copy code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JS Client</title>
</head>
<body>
<script src="js-tutorial.js"></script>
</body>
</html>
but the script is of course the name of your project :)
e
Thanks! And yes, source maps work here
🚀 1
Now I have to understand what goes wrong with node
a
Could you please check if the
.js
files inside the dist directory contain the sourceMap comment at the end?
e
@Artem Kobzar it ends with
Copy code
//# sourceMappingURL=zproto.js.map
a
Hmm, if it's web, could you try to add?
Copy code
"webRoot": "${workspaceFolder}"
Also, there is ``resolveSourceMapLocations`` field, which could also be helpful
e
Oh it's not web, it's a VS Code extension. Not sure if that property has some relevance in this case
a
Okay, so could you try to specify
resolveSourceMapLocations
?
e
I've set
Copy code
"resolveSourceMapLocations": []
So that every location is used to resolve source maps
Might have something to do with
sources
pointing at non-existing files? Being that I'm using the library in another project those relative URLs point to files that do not exist
a
Also, there is an option
sourceMapPathOverrides
:
Copy code
"sourceMapPathOverrides": {
    "*": "${workspaceFolder}/dist/*"
}
e
I did try that one too, to fix the wrong urls, but it did not work. I'll try again tho
a
Also, following the documentation, to resolve every location, you should to put
null
instead of the empty array for `resolveSourceMapLocations`: https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_source-map-resolution
e
Tried that too. Current status is:
Copy code
"resolveSourceMapLocations": null,
"sourceMapPathOverrides": {
  "../../../../../src/*": "C:/Users/edoardo.luppi/IdeaProjects/zproto/src/*",
  "webpack://?:*/*": "${workspaceFolder}/*"
},
I'll check the VS Code devtools, to see if there are hidden errors or warning
Nope, nothing strange going on. I've tried all possible combinations I think.
a
Also, could you try for the
sourceMapPathOverrides
the regular variant :
Copy code
"*": "${workspaceFolder}/dist/*"
Because, as you mentioned, the compiled files contains:
Copy code
//# sourceMappingURL=zproto.js.map
Without the
webpack
prefix
e
Isn't
sourceMapPathOverrides
referring to the
"sources"
field in the
.map
file?
As far as I understood it concats
sourceRoot
with each
sources
entry, and then applies the transformation
@Artem Kobzar I've tried with a fresh Node project, and I can step into the KT sources. I'm not sure what the heck is missing in VSC
That was in intelliJ IDEA, trying again in VS Code and it doesn't work 😐
Ok, made it work in VS Code too. Added
Copy code
"sourceMaps": true,
"resolveSourceMapLocations": [
  "${workspaceFolder}/**",
]
Now I've got to get back to the extension again, but it looks like it's configured in the same way lol
YEESSSSSSSSSSSSSSSSSSSSS I made it work
🚀 2
K 1
So the real issue was the friggin project itself. node_modules was somehow corrupted. I've deleted the entire directory, refreshed all dependencies and now it works. Got to take a day off, what an headache lol Thanks to both of you!
K 1
👏 2
@Adam S @Artem Kobzar i've investigated further and the real difference is the bundling of the VS Code extension. When bundling is done with Webpack, source maps do not work. When you inizialize the extension (
yo code
) and you do not use Webpack as bundler, source maps work.
In case anyone asks again, what happens is VSC extensions can be packaged in different ways. In the image, on the left it's bundled with Webpack, and the right there is no bundling, and dependencies are copied as is. Webpack bundles everything into a single big
extension.js
file, and that's why it messes up the source files. When you start a VSC extension for debugging, the
watch
command is executed. Webpack bundling:
"watch": "webpack --watch",
No Webpack/no bundling:
"watch": "tsc -watch -p ./",
Thus Webpack is bundling even when you want to debug. That's why source maps do not work, or they work intermittently. You can (mostly) workaround the Webpack issue by setting
devtool: 'source-map'
in
webpack.config.js
, although source maps will not be loaded immediately
1