tomashrobarik
Tera Guru

In this article I would like to highlight several debugging tips that you can utilize while developing the now experience components.

console API

One of the most common technique is of course using the native console API. Many developers are using just the simple console.log() all the time for printing messages. But it has a lot more to offer than you may have ever realized.

console.log()

Even when using the simple console.log I usually prefer to wrap my variables into an object. This way I can clearly see which values belong to which variables.

console.log(name, lastName); // prints John, Doe

console.log({name, lastName}); // prints the object {name: "John", lastName: "Doe"}

console.dir()

While console.log() prints the object in its string representation, console.dir() recognizes the object as an object and prints it’s properties in the form of a clean expandable list. This is mostly useful when trying to print the DOM nodes.

const img = document.querySelector("img");

console.log(img); // shows HTML code of a DOM element
console.dir(img); // shows all properties of a DOM element

find_real_file.png

console.assert()

With console.assert(), we can decide only to log something if a condition is false and save some console space by avoiding unnecessary message printing:

// will output the message only if the users array is empty
console.assert(users.length === 0, "There are no users");

console.count()

Instead of incrementing a counter manually, we can use console.count() to do the job for us! We just need to provide it with a label.

const view(state) => {
	console.count("render");
	...
}

// will output
render: 1
render: 2
render: 3

console.table()

Use console.table() to print a visually nice table representation of an object with labeled rows for each the objects’ properties:

console.table(result);

find_real_file.png

Logging with style

This is probably my favorite one. If you want your logs to really standout just use “%c” before a string and pass CSS styles as another argument:

console.log("%c Components are awesome 🌈 ", "font-size: 2rem; color: #333333; padding: 1rem;background-color: #e1ecef")

find_real_file.png

There are definitely much more options that you can utilize but these are one of my favorites.

debugger statement

The debugger statement stops the execution of JavaScript, and calls (if available) the debugging function. Using the debugger statement has the same function as setting a breakpoint in the code.


const view(state) => {
	debugger; //this will stop the execution of code for every re-rendering of the state
...
}

Note: If no debugging is available, the debugger statement has no effect.

Breakpoints in VS Code

In case you are constantly forgetting to delete the debugger statements and you are deploying them to the instance, you can definitely setup those breakpoints in your local development environment. You just need the VS Code, Chrome browser and the appropriate extension installed. You should be able to use other browsers as well, but you would need to install debugger extensions specific for them.

And lastly you need to create a launch.json configuration file like this example below:

{
    "version": "0.2.0",
    "configurations": [
      {
        "type": "chrome",
        "request": "launch",
        "name": "Now Experience",
        "url": "<http://localhost:8081/>",
        "webRoot": "${workspaceRoot}",
        "sourceMapPathOverrides": {
          "webpack:///../src/*.js": "${workspaceRoot}/src/*.js",
          "webpack:///../node_modules/*": "${workspaceRoot}/node_modules/*"
        }
      }
    ]
  }

For more details about creating this configuration file read the official docs at https://code.visualstudio.com/docs/editor/debugging#_launch-configurations

If everything is configured correctly, you should be able to set the breakpoints and examine variables while the code is executing.

find_real_file.png

Render state as JSON

Making breakpoints or observing the console logs might not be always the most efficient way of knowing what is going on. In some cases you might be probably interested only in the current state or the content of some other object. In that case it is very easy to render JSON string in your markup as demonstrated below.

const view(state, {dispatch}) => {
	return (
		<section>
			/*this will render the state as nicely formatted JSON in your HTML*/
			<pre>{JSON.stringify(state, null, 2}</pre>
			...
		<section>
	)
}

Chrome vs Firefox

And lastly I would like to point out a big difference in error handling while using the Firefox browser instead of Chrome. When an error occurs the Firefox will only tell you that COMPONENT_ERROR_THROWN action type is dispatched with error details. But you can't see any detail.

find_real_file.png

However the same error in Chrome will tell you exactly what happened. In the screen below you can clearly see the ReferenceError: functionthatdoesntexist is not defined

find_real_file.png

Version history
Last update:
‎11-24-2020 08:25 AM
Updated by: