whatwg / console

Console Standard
https://console.spec.whatwg.org/
Other
269 stars 67 forks source link

console.json #222

Open wmelton opened 1 year ago

wmelton commented 1 year ago

The vast majority of data transmission in today's javascript ecosystem happens via JSON serialized objects. For node.js developers, serializing objects to inspect them is a mainstay of iterative debugging.

However, as many, many objects are nested, being able to easily inspect the entire object in the console is cumbersome.

console.log(JSON.stringify(<serializable>, null, 2)) has been coded more times in my career than I ever want to count lol.

Given the fact that JSON is ubiquitous in 2023, that JS is object-based by default (meaning the majority of object structures are JSON-serializable), and that it would just be insanely useful, helpful to developers, I want to propose that the whatwg console standard be extended to include console.json

In an ideal world, calling console.json() would perform a similar duty as console.log(JSON.stringify(<serializable>, null, 2)) but with a lot less syntax.

An argument to pretty print or not would seem reasonable. If for verbosity sake an argument to limit the depth of iteration was desired, that would be a reasonable argument/ask in my mind.

Otherwise this seems like a straight-forward and immensely helpful standard extension, especially for node.js developers.

terinjokes commented 1 year ago

There is already a similar console.dir, which is specified as logging the first parameter as a generic JavaScript object. The agents I've tested with have a means of copying as JSON.

wmelton commented 1 year ago

@terinjokes Yeah console.dir isn't a reasonable solution and its not purpose built for the problem most developers are trying to solve when they want to inspect an object.

Example:

(async () => {
  const deepObject = {
    a: {
      b: {
        c: {
          d: {
            e: {
              f: {
                g: {
                  foo: 'bar',
                  array: [1, 2, 3, 4, 5],
                },
              },
            },
          },
        },
      },
    },
  }
  console.dir(deepObject)
})()

Outputs: { a: { b: { c: [Object] } } } which is the problem. I want to see what's in there.

Of course, you can pass the compact flag as false if pretty print is the problem:

{
  a: {
    b: {
      c: [Object]
    }
  }
}

However, much of the object is still obfuscated. Okay, so console.dir then gives us the depth flag. Well, let's look at that:

// console.dir(deepObject, {compact: false, depth: 4})
{
  a: {
    b: {
      c: {
        d: {
          e: [Object]
        }
      }
    }
  }
}

Boo, still [Object]. Well thats because I didn't specify depth far enough. Sigh. Okay lets guess some more about the right depth:

// console.dir(deepObject, {compact: false, depth: 7})
{
  a: {
    b: {
      c: {
        d: {
          e: {
            f: {
              g: {
                foo: 'bar',
                array: [Array]
              }
            }
          }
        }
      }
    }
  }
}

Bollocks! I can see the lower keys now, but still not the values. Of course, I can try again with another depth that will show what array is, but if array was say an array of nested objects, then I'm just iterating and fighting with console.dir to let me easily inspect this thing 🔥 quickly 🔥

Proposed Improvements in console.json

terinjokes commented 1 year ago

When I run your top example in Firefox, I get the following, which I believe is the requested behavior?

{
  "a": {
    "b": {
      "c": {
        "d": {
          "e": {
            "f": {
              "g": {
                "foo": "bar",
                "array": [
                  1,
                  2,
                  3,
                  4,
                  5
                ]
              }
            }
          }
        }
      }
    }
  }
}

I would expect dir to be the same as what you're asking for with json.

wmelton commented 1 year ago

Otherwise this seems like a straight-forward and immensely helpful standard extension, especially for node.js developers.

While it's wonderful that a vendor browser used by 7% of the world does the legwork to expand it automatically, Chrome (77% of global usage) however, does not auto unfurl. They have their own built-in dev tools that make you walk the prototype tree: image

Additionally, backend js developers are a huge segment of the development community today. Unfortunately, the node.js team will not implement this behavior unless whatwg's standard implements it first, which is why I am here. I opened a PR to implement this in node.js core and they sent me here. The examples I provided are from node, but as mentioned, Chrome does not perform as you showed from FireFox(which again, is only 7% of users globally as of this year).

terinjokes commented 1 year ago

How console methods render is implementation defined. This specification defines dir as rendering a generic Javascript object, and Node.js can certainly (and probably should) implement that as a JSON or JSON-like encoding. But that's their call to make.

paulirish commented 1 year ago

Browser consoles are interactive, where's node's console emits non-interactive text to stdout..

It does seem like the proposed solution is to work around node's default depth (and lack of interactivity)... I've left a reply on https://github.com/nodejs/node/issues/46689

wmelton commented 1 year ago

@paulirish agreed, browser consoles are always going to have vendor specific implementations on this stuff.

I originally opened this discussion as a thread in node.js since browsers weren't really what I had in mind from the start.

I was told by that team to come here, so thats why I'm here lol.

Thanks for commenting on the original thread.

domfarolino commented 1 year ago

I was told by that team to come here, so thats why I'm here lol.

Unfortunately I don't think there is too much here that's actionable since as Terin mentioned, this is very much implementation-specific territory. That is, if we were to spec console.json, it would be subject to the same implementation-specific liberties that the spec gives for other APIs. Given that I don't see much of a path forward, I might recommend closing this issue.

wmelton commented 1 year ago

@domfarolino for me, I still think that it should be considered more significantly.

In 2023, JSON is a first class citizen with a nearly unmatched ubiquity in the web-development world.

While there are of course vendor specific details and implementation-specific liberties in the console spec, console.dir does not achieve the same goal as console.json.

To tackle the browser implementation-specific objection head-on, I would argue that in heavy debug cycles, being able to stringify an object directly to JSON via (console.json(<serializable)) in the developer console would be immensely useful far and above what console.dir achieves because of the interoperability and usability of getting data in to JSON quickly and easily for use in other dev tools.

Further, I would argue that console.json has no implementation-specific considerations or liberties since JSON is well defined by RFC-8259, and, unlike console.dir, the output format is fixed: its a string, as defined by it's RFC.

This simplifies and removes ambiguity about browser-specific implementations since JSON is a string, and since auto-magic object tree structuring in browser UIs generally exists already, there would be no reason for browsers to implement console.json in any other fashion than to print the serializable object to the console in its string form.

The suite of console.* functions are largely utility functions anyhow, meant to help, assist, and improve the developer experience. console.json would bolster that value proposition, improve developer experience, and also provide a pathway for backend js projects (like node) to implement it as well.

Thanks again for your consideration on this topic.

terinjokes commented 1 year ago

I think this would be better resolved by working with your user-agent to provide the options you want to for console.dir, rather than requiring one specific encoding. I have concerns around serialization and transmission requirements needed in remote debugging scenarios, and console.dir allows agents to use other structures more suitable for their environments (eg, Nyxt might use lists or cons).

wmelton commented 1 year ago

@terinjokes On the browser side, I hear ya. The challenge is, the node.js team follows your standard strictly (which is why they sent me here). So this is not an issue I feel necessarily needs to be addressed for browser-based development where use-agent is in play, but about the downstream subscribers to this standard like node.js.

Maybe if you know anyone on the node.js team, you can let them know these types of deviations are anticipated in contexts where we are dealing with a specific applications implementation of the standard?