Debugging SJS in Microsoft Visual Studio 2015

25 views
Skip to first unread message

ane...@certify.com

unread,
Nov 3, 2016, 10:16:38 PM11/3/16
to StratifiedJS
Hello!

My next step in achieving developer productivity nirvana is to figure out how to get integrated debugging working with Stratified.js code within Visual Studio 2015.

This involves files that have extension .sjs which get loaded using require, as well as inline scripts that have the type="text/sjs" attribute.

(Thankfully, I now have the require function working great!)

I believe I may be part of the way to getting debugging to work because I went into Tools/Options/File Extension and added sjs and pointed it to the JavaScript Editor. I also tried checking the checkbox at the bottom of that page that says "Map extensionless files to:" and I selected JavaScript Editor. These settings have made the text editor so that now it provides color coding and intellisense right in my .sjs files. GREAT!

Next step is to get debugging to work. I can set a breakpoint in my .sjs file, and before I run the project the breakpoint has a solid red circle so it looks like it is going to work. But when I run the project the solid red circle changes to have a white center, and the breakpoint does not fire when execution gets to it. Furthermore, when I float my mouse over that breakpoint, I get this message in the IDE:

The breakpoint will not currently be hit. No symbols have been loaded for this document.
Location: CMStratified.sjs, line 199 character 2


I realize this is a question that is specific to Visual Studio, and believe me I am going to scour the web tomorrow for a solution. But this is also a question that the kind folks that make Stratified.js may have encountered before. It is also a question that, once answered, will provide lots of value to the Stratified.js community because of the popularity of Visual Studio and the high level of developer productivity that this solution will afford.

Many thanks for all thoughts!

ane...@certify.com

unread,
Nov 6, 2016, 8:18:02 PM11/6/16
to StratifiedJS, ane...@certify.com
I have continued to think about this issue. It seems that Stratified.js is really a "transpiler" that transpiles SJS code and any module that is loaded using require *at run time*. Some transpilers function at build time, and that allows an IDE to at least debug into the transpiled code. But if the transpiler does its magic at run time, then it becomes quite difficult to inform the debugger about the symbols that map the running code back to the original source code. In addition, Stratified.js is doing a ton of work for us when it does its magic, and so even if I were to get this to work, it seems that the transpiled code would be quite different from the original source, and that it would therefore be very difficult to debug and then manually map back to the original source in the developer's brain.

That said, I am getting one VERY NIFTY thing working, and it is this... If my code generates an error, I am getting a line in the output window that tells me basically what happened, along with the actual line number of my original source. This much gives me hope, and it is also very helpful. The trouble is that the IDE does not stop on any of those errors and go into debug mode. I wish it did. I'll keep playing with that.

Any comments from Alex?

Alan

Alexander Fritze

unread,
Nov 7, 2016, 11:43:07 AM11/7/16
to strati...@googlegroups.com
I don't want to say it is impossible, but it would at least be very
hard to get SJS to play nice with a conventional debugger. The main
problem is that SJS's idea of the call stack is different to the
underlying JS engine's idea of the call stack. Consider e.g. the
function:

function foo() {
do_something();
hold(1000);
do_something_else();
}

This gets executed by the JS engine as something like:

do_something();
setTimeout(do_something_else, 1000);

Because of the single-event-loop design of JS, if you were to set a
breakpoint on "do_something_else", by the time this line executes you
will have lost the remainder of the call stack, so all you'll see is
"do_something()". The caller ("foo" and everything on top of "foo")
will be missing.
> --
> You received this message because you are subscribed to the Google Groups
> "StratifiedJS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to stratifiedjs...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

ane...@certify.com

unread,
Nov 7, 2016, 12:20:31 PM11/7/16
to StratifiedJS
That makes sense, I get it!

In lieu of being able to debug SJS code, my next best choice is to minimize the amount of code that I am running as SJS. So my goal would be to move some code from inline SJS into plain javascript. While doing this I am encountering a problem. The way the new design should work is that standard javascript calls into an SJS object to call a function, which looks like this:

objLoginResult = cm.getJSONResult({ Username:strUsername, Password:strPassword });

The function called getJSONResult is inside a file called CMStratified.js which is SJS code and is loaded using require. The getJSONResult function uses waitfor() to cause a JQuery $.ajax call to become synchronous. Before I moved this line of code from inline SJS to plain javascript, everything worked fine. But now that this line has been moved to plain javascript for some reason the cm.getJSONResult function does not wait like it should - it just zooms past and the next lines of code error out because objLoginResult is undefined.

Got any tips here? Is there something basic that I'm not doing right?

A

Alexander Fritze

unread,
Nov 7, 2016, 12:51:23 PM11/7/16
to strati...@googlegroups.com
Right, if you call an SJS function from JS, and the SJS function does
something asynchronous under the hood, then there's no way normal JS
can just synchronously get the result back. That's the reason we have
SJS in the first place :-)

You have to go the detour via a promise/callback/deferred or similar.

One possibility is to use
https://conductance.io/reference#sjs:function::deferred (somewhat
outdated description here:
https://groups.google.com/d/msg/stratifiedjs/fXN-euKGhFA/0ajgeefzqfAJ
).

In your particular case:

// in CMStratified.js:
var getJSONResultDeferred = require('sjs:function').deferred(getJSONResult);

// in JS:

cm.getJSONResultDeferred.then(
function(objLoginResult) {
use_login_result(objLoginResult)
},
function(error) {
handle_error(error);
}
)

ane...@certify.com

unread,
Nov 17, 2016, 7:21:17 AM11/17/16
to StratifiedJS
I just read this post:


How about if there was a way we could call stratified.js before execution and tell it the name of our .sjs file, and have it spit out a source map? Then we could set up our IDE to execute that automatically before running a project, and we would have an up to date source map file saved to disk. Any chance that creating a source map generation function is a possibility?


On Monday, November 7, 2016 at 11:43:07 AM UTC-5, Alexander Fritze wrote:
Reply all
Reply to author
Forward
0 new messages