Is possible to debug dynamic loading JavaScript by some debugger like WebKit, FireBug or the IE8 Developer Tool?
Asked Answered
S

11

96

From my recent question, I have already created some JavaScript functions for dynamic loading of a partial view. But I can't debug any dynamic loading JavaScript. Because all of the loaded JavaScript will be evaluated by the "eval" function.

I found one way to create new JavaScript by using the following script to dynamically create the script into the header of current document. All loaded scripts will be displayed in the HTML DOM (and you can use any debugger to find it).

var script = document.createElement('script')
script.setAttribute("type","text/javascript")
script.text = "alert('Test!');";

document.getElementsByTagName('head')[0].appendChild(script);

By the way, most debuggers (IE8 Developer Toolbar, Firebug and Google Chrome) can’t set breakpoints in any dynamic script. Because debuggable scripts must be loaded the first time after the page is loaded.

Do you have an idea for debugging when using dynamic script content or a dynamic file?

Update 1 - Add source code for testing

You can use the following xhtml file for trying to debug someVariable value.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>    
    <title>Dynamic Loading Script Testing</title>
    <script type="text/javascript">
    function page_load()
    {       
        var script = document.createElement('script')
        script.setAttribute("id", "dynamicLoadingScript");
        script.setAttribute("type","text/javascript");
        script.text =   "var someVariable = 0;\n" +
                        "someVariable = window.outerWidth;\n" +
                        "alert(someVariable);";
        
        document.getElementsByTagName('head')[0].appendChild(script);
    }
    </script>
</head>
<body onload="page_load();">
</body>
</html>

From answer, I just test it in FireBug. The result should be displayed like below images.

alt text

Please look at the "dynamicLoadingScript" that is added after page load.

alt text

But it is not found in the script tab of FireBug

Update 2 - Create Debug Breakpoint in dynamic loading script

alt text

alt text

Both of the above images show inserting "debugger;" statement in some line of the script can fire a breakpoint in the dynamic loading script. However, both debuggers do not show any code at breakpoint. Therefore, it is useless to this

Thanks

Successor answered 10/11, 2009 at 6:14 Comment(5)
Did you happen to find a solution for this? I'm here with the same problem.Monseigneur
Try loading a separate file dynamically ie see here for an implementation queryj.com/2011/03/11/a-lightweight-script-loader - I find the debuggers handle that far more easily.Apocalyptic
@infinity, check out my solutionSwanee
2014 and your images are still dead - Can you reup them?Gildagildas
I have a similar question but I can't tell because the images are broken. Can you update them?Handwriting
M
124

It would also be possible to use chrome for the same. Chrome has a feature where you can specify a parser attribute and make the piece of dynamic JS appear as a file which can then be browsed to and break points set.

the attribute that needs to be set is

//# sourceURL=dynamicScript.js

where dynamicScript.js is the name of the file that should show up in the script file browser.

More information here

Paul Irish also talks about it briefly in his excellent talk on Tooling & The Webapp Development Stack

Michaelson answered 7/6, 2012 at 9:47 Comment(8)
In case someone is having issues with MVC3/Razor, remember to escape the @ symbol, so something like //@@ sourceURL=dynamicscript.js And just fyi, the above works in firebug as well.Emeraldemerge
You can use this feature for dynamic inline javascripts as well. But, if you have some exception in that script, you will not see it in the sources list.Marilumarilyn
Note that new syntax is "//# sourceURL=dynamicScript.js" change from @ to #Floydflss
the updated link to the chrome developer tools section on source maps is - developer.chrome.com/devtools/docs/…Predicate
For me, the js file was being displayed in the sources list within a group called "(no domain)". Might be worth mentioning as I missed it at first!Sustain
For some reason, this only worked for debugging when I placed it at the bottom of the javascript, not at the top. It would still rename VM### to the correct name, but breakpoints refused to break.Veedis
@Sustain it's that very reason you're unable to locally map (via workspaces) to that dynamic JS. Unfortunate, and hoping I'm mistaken.Garfield
revised link for latest google documentation: developers.google.com/web/tools/chrome-devtools/javascript/…Pique
U
21

Try adding a "debugger;" statement in the javascript you're adding dynamically. This should cause it to halt at that line regardless of breakpoint settings.

Urba answered 10/11, 2009 at 9:57 Comment(3)
All I can find is this: code.google.com/p/fbug/issues/detail?id=1259 . By the way, I use script tag appending to the head to dynamically load scripts (but using a src attribute), and the code added this way is debuggable for me on all browsers, even if it's not loaded together with the initial page.Urba
What's the exact code you're using to add the script tag? I'm having the same issue as the OP, which is making it impossible to debug dynamically loaded JS files in Chrome. Thx!Monseigneur
var loaderNode = document.createElement("script"); loaderNode.setAttribute("type", "text/javascript"); loaderNode.setAttribute("src", url); document.getElementsByTagName("head")[0].appendChild(loaderNode);Urba
O
19

Yes, It is (now) possible to debug dynamically loaded JavaScript using Google Chrome!

No need to add extra debugger; or any other attribute for dynamically loaded JS file. Just follow the below steps to debug:

Method 1:

My tech lead just showed a super-easy way to debug dynamically loaded Javascript methods.

  1. Open Console of chrome and write the name of the method and hit enter.
    In my case, it is GetAdvancedSearchConditonRowNew
    If the JS method has loaded then it will show the definition of the method.

enter image description here


  1. Click on the definition of the method and the whole JS file will be opened for debugging :)

enter image description here


Method 2:

As an example, I'm loading JS file when I click on a button using ajaxcall.

  1. Open network tab in google chrome dev tools
  2. Click on a control (ex. button) which loads some javascript file and calls some javascript function.
  3. observe network tab and look for that JS function (in my case it is RetrieveAllTags?_=1451974716935)
  4. Hover over its initiater and you'll find your dynamically loaded JS file(with prefix VM*).

debug dynamic loading JavaScript in chrome -1


  1. Click on that VM* file to open.
  2. Put debugger whereever you want in that file :D

debug dynamic loading JavaScript in chrome -1


Oppilate answered 11/1, 2016 at 5:37 Comment(1)
Shame on Google for making this so obtuse. 1 / Shame = Kudos (the inverse of shame) to you for pulling it out :)Wilbur
S
15

I'm using google chrome for that purpose.

In chrome at scripts tab you can enable 'pause on all exceptions'

enter image description here

And then put somewhere in your code line try{throw ''} catch(e){}. Chrome will stop execution when it reaches this line.

EDIT: modified image so it would be clearer what I'm talking about.

Swanee answered 19/7, 2011 at 9:58 Comment(4)
For develop in Google Chrome, you should insert some text that indicate the name of current dynamic script when jQuery or any other loading script append script to DOM like I reported to jQuery team. But I don't have time to work on it. bugs.jquery.com/ticket/8292Successor
@Soul_Master, but using my method you don't need to insert text. You insert in your dynamic script line try{throw ''} catch(e){} then enable 'pause on all exceptions' mode and chrome will stop execution when exeption is thrown. I've checked it many times. I loaded another image. It is clearer there what I'm talking about.Swanee
In chrome, you can use " debugger; " statement to break at a statement when debugger panel is open. Chrome will simply ignore this if the debugger panel is closed.Poss
@dineshygv, you can ... now. But you could not 3 years ago. debugger wouldn't work in dynamically created script back then.Swanee
C
10

I think you might need to give the eval'd code a "name" like this:

http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/

If you do, I think it's likely the debugger approach from "update 2" should work then.

Croon answered 19/5, 2011 at 21:27 Comment(4)
Yes. I see it. I already reported this bug to jQuery team for a long time. bugs.jquery.com/ticket/8292Successor
Warning! the technique described causes an error in IE7, so don't leave the //@ sourceURL=blah in production.Spendable
it's probably the debugger part that causes issues, not the source comment (which is surely ignored by JS)Croon
It can cause problems with ie conditional compilation. e.g.: javascriptkit.com/javatutors/conditionalcompile.shtmlSpendable
L
4

UPDATE: the syntax for sourceUrl has been changed (@ is replaced by #) to avoid errors on unsupported browsers (read: IE). Details

Langevin answered 12/7, 2013 at 9:11 Comment(0)
G
2

Using Chrome(12.0.742.112) with the code you provided plus a debugger statement like this

    script.text =   "debugger;var someVariable = 0;\n" +
    "someVariable = window.outerWidth;\n" +
    "alert(someVariable);";

chrome_debugger

works for me.

I need to modify some JavaScript (limiting scope of all jQuery selector to current partial >view div) before execute it.

May its more tangible if you bind the selector change to an event on your partial view instead of creating script elements in the html body ( doesnt feel right ).

You could do something like this

   (function(j)(
      var limiting_selector = '';
      j(".partial_views").bind('focusin over',function(e){
         limiting_selector = j(this).attr('someattr') // or j(this).data('limiting-selector')
      }).bind('focusout out',function(e){
         limiting_selector = '';
      });
      // And then go on with
      // j(limiting_selector+' .someclass')
   ))(jQuery)

This code would always add a limiting selector to all jQuery select operations done while the mouse is in a certain element given the HTML isnt to messed up.

(Still seems hackerish, may be someone has a better solution)

cheers

Gazette answered 6/7, 2011 at 6:18 Comment(0)
M
1

In Firebug, you should be able to see that script after the page is loaded and the script is injected. When you do, you can set a breakpoint in the appropriate place, and it'll be preserved when you refresh the page.

Mokas answered 10/11, 2009 at 6:27 Comment(2)
You're right. That doesn't work. I tried it with eval() and Firebug will let you set a breakpoint when you use that. Is there a reason you can't use eval() and need to set a script tag? Even more generally, is there a reason you can't serve this dynamic javascript as a separate .js file on your server? What problem are you trying to solve?Mokas
I need to modify some JavaScript (limiting scope of all jQuery selector to current partial view div) before execute it. Or you have any idea for solving my recent question. For more information please look at my recent question.Successor
T
1

Dynamicly loaded Javascript still has to be parsed by the browser this is where WebKit, or FireBug debugger is sat so it's subject to the debugger no matter what, i think this is the same for the developer tools in IE8,

So your code is subject is to the debugger so where your getting a problem will not be in that file or text if it does not error

The other thing is script.text = "alert('Test!');"; is not valid so it wont work in all browsers what you want is script.innerHTML = "alert('Test!');";

even though its innerHTML it means code inside the HTML Tags not the HTML inside just the most use people use it for this so it gets explained wrong

EDITED FOR UPDATE TWO

And on Second update using Chrome i did this

go to about:blank Open the console up and past in

var script = document.createElement('script')
script.setAttribute("type","text/javascript")
script.innerHTML = "alert('Test!');debugger;";

document.getElementsByTagName('head')[0].appendChild(script);

then it will break and open the script tab with about:blank shown (nothing to see)

Then on the right hand side show the call stack list, then click on the second (anonymous function) and it will show you.

So on your file you will have a (anonymous function) that is the code your running and you will see the break point in there. so you know your in the right one.

Tinner answered 26/5, 2011 at 14:31 Comment(0)
B
0

Using Google Chrome (or Safari) Developers Tool, you can run JavaScript line by line.

Developer Tool > Scripts > Choose which script you want to debug > pause sign on the right side Or set breakpoints by click the line number

Bandaranaike answered 19/6, 2011 at 20:12 Comment(0)
G
0

One option I like to use it adding a console.log('') statement in my code. Once this statement appears in the console a line number is associated with it. You can click that number to go to the location in the source and set a breakpoint. The drawback to this approach is that breakpoints are not preserved across page reloads and you have to run through the code before you can add a debugger.

Gatian answered 17/12, 2014 at 19:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.