is there any option to set something like "breakpoint" on a file in chrome console (kindof shortcut to set breakpoint on every line of code in the file)?
Would be extremely useful when trying to understand 3rd party scripts that you know are executed but have no idea which part of code and from where is executed when.
My current example use case: I downloaded a script (form validation) which does not work as expected. The fastest way to solve the problem would be to pause execution anytime JS runtime enters this file and start exploring it from there.
I think this will be of use to you. I've recently been doing some work on the JavaScript Breakpoint Collection Chrome Extension created by Matt Zeunert, which allows you to inject breakpoints into your code at runtime - including breaking on property access/modifications, functions, scrolling events, etc. You can break on any arbitrary objects as well as the predefined ones using the console API.
Check out the project here.
If you can enumerate the functions publicly exposed by your third party script (for example if they are all properties of an object, or is their name has a pattern) you can make another script which dynamically replaces all those functions and force a break point :
thirdpartfunc = (function () {
var oldfunc = thirdpartfunc;
return function () {
debugger;
oldfunc.call(null, arguments);
}());
With the appropriate binding to this (if any applicable).
If you know the function(s) being called, you can use function breakpoints
debug(function);
function(...args);
When you call the function, it will hit the breakpoint. These aren't saved on page reload, but you can set a line breakpoint once you hit the function breakpoint.
This can get kinda tedious though.
If you have a array of functions, you can do
[function0, function1].map(debug)
#Tibos answer in another post would be good if there was some sort of babel transform to insert debugger; at the start of every function, instead of inserting it manually.
The quickest way for me was to do a global replace of the function declarations in the source, adding "debugger;" at the start.
In other words, replace
function [^{]*{
with
$0 debugger;
Your regexp may vary depending on the escapes you need. For example:
function [^{]*\{
You may also need more than one pattern to handle all the function declarations you have.
This has nothing to do with the Chrome console though.
No. You would have to add breakpoints to the various function entry points that file contains to catch everywhere it could enter.
Can't you just place a breakpoint at the first line of every function in the file of interest?
Related
I'd love to live in a lint free world. JSLint that is. But I'm having some problems that I'm not sure I should ignore or fix. Specifically I'm getting a number of:
[functionName] not defined
errors. I do recognise that you should always define the function before using it and I assume that's what the message is really warning against but here are two cases where I think there is a valid exception:
jQuery(document).ready(function($) {
// code goes here
}
In a simple file which starts with a typical noconflict wrapper for jQuery I get a warning saying that "jQuery(document).ready(function($) {" is not defined. Obviously jQuery is defined in a separate file that needs to stay separate. Does that make sense?
The second example is really quite similar although arguably it is more avoidable. In this case I have two JS files in my project. One that looks just like the one above (aka, it's a set of DOM triggered events wrapped inside of jQuery's "ready" event). The other has a number of helper functions that look like this:
function doSomethingImportant() { };
function doSomethingImpressive() { };
These functions are then called within the first JS file. JSLint doesn't like this and complains every time the first JS file calls a function defined in the second JS file: doSomethingImportant() { is not defined. Yet in reality, since the functions are defined at load time and the calls to those functions always happen afterward based on DOM events there never seems to be a real problem.
Anyway, open to ideas. Is this a case of filtering JSLint's advice or something I should fix in code?
You're getting these errors because JSLint assumes that at some point in the future you might do:
var doSomethingImpressive = function() { }
in which case you would get an error, because the file where the function is defined is included after the function call (as explained here)
The same goes for the jQuery call. You can either change the order of your scripts, or safely ignore the errors.
After using functionality from this question for debugging I am wondering is there a way to get the file name from which the function was invoked and may be the line.
May be I am asking for too much, but I know that in some of the languages it is possible.
If this is not possible can anyone mention why his functionality was not implemented?
I will try to rephrase the question, because I think I didn't make myself clear.
I have file.js in which on the 17-th line there is a declaration of the function:
...
function main()
{
Hello();
}
I have another file test.js, where I define function hello
function Hello()
{
...
which tells me the name of the file and a line in which the function which evoked it was defined
}
So for example if I will call
main(), it will tell me file.js, 17 line
It has nothing to do with firebug
If all your doing is debugging, hy not just use the debugger built into modern browsers?
debugger
That line is all you need. You can examine the callstack, inspect variable values, and even run code in the current scope.
Such functionality makes your request kind of unnecessary.
You don't mention what browser you are using.
In Chrome what I would suggest is inserting a breakpoint on the first line of the function. Then reload the page (or otherwise trigger the function call). When execution pauses at the breakpoint, check the Call Stack section in Chrome's Developer tools - it will give you a stack back-trace of the flow of execution.
I'm sure Firebug offers something similar if not identical, it's just been a while since I used it.
Cheers
I've seen some of the console wrappers that stop errors in browser with a console and more advanced ones that enable logging in older browsers. But none that I've seen help switch on and off the debug code.
At the moment I do a find and replace to comment out debug code. There must be a better way?
I'm using Combres which uses YUI to minify the JavaScript. I've seen some posts that mention using double semi colons to mark lines to be removed in the minification process. Is this a hack or good practice?
Probably you should have your own wrapper around console.log() and log your debug info via that wrapper. That way you can replace that single function with an empty function once you deploy to production so the console won't flood with debugging info. You can also replace the actual console.log function with an empty function, but that would prevent any Javascript from outputting to console, not just yours.
If you look at how the YUI Framework does it, they actually use a regex and generate 3 files from source. One that has the logging -debug, one that has the logging stripped out, just the file name, and a minified version with no logging. Then you can set a global config to say which version you want. I've worked that way in the past and works nicely.
Define your own debugging function that'd be wrapper around console.log or anything else you want and make sure that minifier can easily deduce that it is no-op if you make it empty. After that, once you comment function body out, most minifiers should detect that there's nothing to call or inline and remove references to your function completely.
Here's the example:
(function() {
function debug() {
console.log(arguments)
}
function main() {
debug(123)
alert("This is production code!")
debug(456)
}
main()
})()
I've put it into anonymous function to restrict scope of debug and don't let it be assigned to window - that allows minifier to easily decide if it is necessary or not. When I paste this code to online GCC, I get:
(function(){function a(){console.log(arguments)}a(123);alert("This is production code!");a(456)})();
But once I add // before console.log to make debug empty, GCC compiles it to:
(function(){alert("This is production code!")})();
...removing all traces of debug code completely!
Use Y.log() instead, and then you can use gallery-log-filter to filter the log messages that you want to see printed.
I want to force the Chrome debugger to break on a line via code, or else using some sort of comment tag such as something like console.break().
You can use debugger; within your code. If the developer console is open, execution will break. It works in firebug as well.
You can also use debug(function), to break when function is called.
Command Line API Reference: debug
Set up a button click listener and call the debugger;
Example
$("#myBtn").click(function() {
debugger;
});
Demo
http://jsfiddle.net/hBCH5/
Resources on debugging in JavaScript
http://www.laurencegellert.com/2012/05/the-three-ways-of-setting-breakpoints-in-javascript/
http://berzniz.com/post/78260747646/5-javascript-debugging-tips-youll-start-using-today
As other have already said, debugger; is the way to go.
I wrote a small script that you can use from the command line in a browser to set and remove breakpoint right before function call:
http://andrijac.github.io/blog/2014/01/31/javascript-breakpoint/
debugger is a reserved keyword by EcmaScript and given optional semantics since ES5
As a result, it can be used not only in Chrome, but also Firefox and Node.js via node debug myscript.js.
The standard says:
Syntax
DebuggerStatement :
debugger ;
Semantics
Evaluating the DebuggerStatement production may allow an implementation to cause a breakpoint when run under a debugger. If a debugger is not present or active this statement has no observable effect.
The production DebuggerStatement : debugger ; is evaluated as follows:
If an implementation defined debugging facility is available and enabled, then
Perform an implementation defined debugging action.
Let result be an implementation defined Completion value.
Else
Let result be (normal, empty, empty).
Return result.
No changes in ES6.
On the "Scripts" tab, go to where your code is. At the left of the line number, click. This will set a breakpoint.
Screenshot:
You will then be able to track your breakpoints within the right tab (as shown in the screenshot).
There are many ways to debug JavaScript code. Following two approaches are widely used to debug JavaScript via code
Using console.log() to print out the values in the browser
console. (This will help you understand the values at certain points
of your code)
Debugger keyword. Add debugger; to the locations you want to
debug, and open the browser's developer console and navigate to the
sources tab.
For more tools and ways in which you debug JavaScript Code, are given in this link by W3School.
It is possible and there are many reasons you might want to do this. For example debugging a javascript infinite loop close to the start of the page loading, that stops the chrome developer toolset (or firebug) from loading correctly.
See section 2 of
http://www.laurencegellert.com/2012/05/the-three-ways-of-setting-breakpoints-in-javascript/
or just add a line containing the word debugger to your code at the required test point.
Breakpoint :-
breakpoint will stop executing, and let you examine JavaScript values.
After examining values, you can resume the execution of code (typically with a play button).
Debugger :-
The debugger; stops the execution of JavaScript, and callsthe debugging function.
The debugger statement suspends execution, but it does not close any files or clear any variables.
Example:-
function checkBuggyStuff() {
debugger; // do buggy stuff to examine.
};
You can set debug(functionName) to debug functions as well.
https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints#function
I wouldn't recommend debugger; if you just want to kill and stop the javascript code, since debugger; will just temporally freeze your javascript code and not stop it permanently.
If you want to properly kill and stop javascript code at your command use the following:
throw new Error("This error message appears because I placed it");
This gist Git pre-commit hook to remove stray debugger statements from your merb project
maybe useful if want to remove debugger breakpoints while commit
I have an ASP.NET MVC project that uses some simple AJAX functionality through jQuery's $.get method like so:
$.get(myUrl, null, function(result) {
$('#myselector').html(result);
});
The amount of content is relatively low here -- usually a single div with a short blurb of text. Sometimes, however, I am also injecting some javascript into the page. At some point when I dynamically include script into content that was itself dynamically added to the page, the script still runs, but it ceases to be available to the debugger. In VS2008, any breakpoints are ignored, and when I use the "debugger" statement, I get a messagebox saying that "no source code is available at this location." This fails both for the VS2008 debugger and the Firebug debugger in Firefox. I have tried both including the script inline in my dynamic content and also referencing a separate js file from this dynamic content -- both ways seemed to result in script that's unavailable to the debugger.
So, my question is twofold:
Is there any way to help the debugger recognize the existence of this script?
If not, what's the best way to include scripts that are used infrequently and in dynamically generated content in a way that is accessible to the debuggers?
I can not comment yet, but I can maybe help answer. As qwerty said, firefox console can be the way to go. I'd recommend going full bar and getting firebug. It hasn't ever missed code in my 3 years using it.
You could also change the way the injected javascript is added and see if that effects the debugger you're using. (I take it you're using Microsoft's IDE?).
In any case, I find the best way to inject javascript for IE is to put it as an appendChild in the head. In the case that isn't viable, the eval function (I hate using it as much as you do) can be used. Here is my AJAX IE fixer code I use. I use it for safari too since it has similar behavior. If you need that too just change the browser condition check (document.all for IE, Safari is navigator.userAgent.toLowerCase() == 'safari';).
function execajaxscripts(obj){
if(document.all){
var scripts = obj.getElementsByTagName('script');
for(var i=0; i<scripts.length; i++){
eval(scripts[i].innerHTML);
}
}
}
I've never used jquery, I preferred prototype then dojo but... I take it that it would look something like this:
$.get(myUrl, null, function(result) {
$('#myselector').html(result);
execajaxscripts(result);
});
The one problem is, eval debug errors may not be caught since it creates another instance of the interpreter. But it is worth trying.. and otherwise. Use a different debugger :D
This might be a long shot, but I don't have access to IE right now to test.
Try naming the anonymous function, e.g.:
$.get(myUrl, null, function anon_temp1(result) {
$('#myselector').html(result);
});
I'm surprised firebug is not catching the 'debugger' statement. I've never had any problems no matter how complicated the JS including method was
If this is javascript embedded within dynmically generated HTML, I can see where that might be a problem since the debugger would not see it in the initial load. I am surprised that you could put it into a seperate .js file and the debugger still failed to see the function.
It seems you could define a function in a seperate static file, nominally "get_and_show" (or whatever, possibly nested in a namespace of sorts) with a parameter of myUrl, and then call the function from the HTML. Why won't that trip the breakpoint (did you try something like this -- the question is unclear as to whether the reference to the .js in the dynamic HTML was just a func call, or the actual script/load reference as well)? Be sure to first load the external script file from a "hard coded" reference in the HTML file? (view source on roboprogs.com/index.html -- loads .js files, then runs a text insertion func)
We use firebug for debug javascript, profile requests, throw logs, etc.
You can download from http://getfirebug.com/
If firebug don't show your javascript source, post some url to test your example case.
I hope I've been of any help!
If you add // # sourceURL=foo.js to the end of the script that you're injecting then it should show up in the list of scripts in firebug and webkit inspector.
jQuery could be patched to do this automatically, but the ticket was rejected.
Here's a related question: Is possible to debug dynamic loading JavaScript by some debugger like WebKit, FireBug or IE8 Developer Tool?