k6 is not nodejs based and also has no debugger of its own. So there is no way for visual studio code to debug k6 scripts. The error you see is because it tries to run it in nodejs and “k6” is not a module nodejs recognises.
Some thoughts on this:
k6 can get a debugger … I have no idea what this will entail, but it will probably be a lot of work and is likely to not be compatible with anything else, which will practically negate the majority of the benefits
we can reimplement the k6 modules for nodejs so you can debug them. There have been people who wanted to use their (request making) nodejs code to be run in k6, but if they use these modules in nodejs … it will also work in k6. The implementation won’t be exactly the same so there will be subtle differences which means that if you are debugging something complex you might get different behaviour. Also this will be a lot of work.
Are you doing something complex enough that console.log won’t help you? As this is the only "debugger’ currently and given my reasoning above, it is unlikely to change … soon .
I was afraid of that but I was hoping there would be a way around it.
I understand. Thank you very much for the explanation.
We have just started a project using k6 and I was doing a ‘research task about it’. I believe console.log will help us.
I found it helpful to run k6 via HTTP proxy such as https://mitmproxy.org/. Also if you need to debug your own code and you factor it into a separate module, then you can use the usual node debugger tools.
is likely to not be compatible with anything else, which will practically negate the majority of the benefits
I think that integration of such a debugger with the IDE could be done with the comparable efforts.
Anyway, having a debugger for a tool with scripting capabilities is a big advantage for this tool.
we can reimplement the k6 modules for nodejs so you can debug them.
That sounds like a good and straight forward solution to the problem. Is there a technical reason (e.g. performance) for the built-in modules not written in JS at the first place? Is it realistic to expect mirroring functionality to be implemented as an NPM module and supported alongside with the main product?
No, or at least the k6 core dev team doesn’t plan to do it. It’s quite the significant amount of work, and even if it’s done once, having to maintain 2 separate implementations of the same API will have huge ongoing maintenance costs.
The reasons the k6 core is written in Go are many, but the standard Go HTTP library and better multi-core performance are two big ones. Every VU in k6 is a separate and (mostly) independent JavaScript runtime.
Thanks for the prompt response! I didn’t mean to reimplement whole core and functionality in NodeJS instead or alongside Go implementation, you guys did a great job explaining the reasoning for using Go instead of NodeJS in the documentation. I apologize for not being clear.
What I mean was to keep core in Go, and either to reimplement the built-in module only in JS, or to have the built-in module JS implementation alongside with the implementation within the core. The JS implementation could be as simple as possible, even dummy stubs with the compatible signatures would be a great step froward (according to k6 JavaScript API it could be just few tens of simple functions).
That would let run a single VU in NodeJS to run the script using the NodeJS debugger. Actual load runs would still be via k6 core written in Go.
We now have a significant amount of code in our k6 repo and we have come to a point where the lack of debugging is hurting us. I’ll investigate how much effort this actually is – seems reasonable for what we need and I suspect others as well.
There is a POC debugger for k6 that is not merged into Goja yet.
Details
A while ago I started experimenting with Goja, the underlying JS engine of k6 and DAP, LSP and LSIF on VS Code and I was convinced back then that the only way to debug k6 code is to implement a debugger in Goja, which was exactly what I did, although with its own limits and shortcomings.
I created a CLI frontend application, Goja Debugger, to demonstrate the capabilities of the new debugger. This new debugger has the basic functionalities needed for the Goja to be able to debug a JS script, as mentioned here. Also, there has been lots of discussions around it and I also filed a PR for review. You can also have a look at the tests@mstoykov and I wrote for the debugger implementation in Goja.
@mstoykov helped improve the code a lot after my initial POC and also created a POC debugger frontend with 1 VU inside k6 to show how the debugger works, which you can compile and test.
There is still road ahead for the debugger to be improved and possibly merged in Goja. Finally the DAP needs to be implemented as another frontend for the debugger. I created a stub/skeleton for the DAP server here.
Aside from @mstoykov and I, a lot of people helped make this possible, notably Niels Widger for testing and suggestions and recently Zhongxian Pan who contributed code and filed lots of issues and PRs. So, if you are interested in the debugger, please help test and improve/develop it. I’d be happy to help and review the PRs and answer the issues.
The project is archived, because we are not going to work on it anymore AFAIK, aka. abandoned for now. But if there’s a contributor, I’d be happy to help review it. There are other issues as well, for example, you can’t debug your script in a distributed manner, hence you default to 1 VU for debugging, which might not be what you want. Otherwise your JS linter can probably catch a lot of issues. You can use the @types/k6 to further lint and validate your code.
I frequently debug my k6 scripts in node using VS code, I would find K6 unusable for my purposes without it and fall back onto something with better debugging functionality.
The method I use is to create a few polyfill functions and use the “require” syntax to determine which modules to load at runtime.
The things to keep in mind are that this method doesn’t support the k6 wrapper for load generation so the user model with which transactions are fed in is arbitrary. There are some differences in behavior between goja and node that you can come across too.
Its not perfect but gets the job done for testing functionality.