11

I've recently started using proxies in one of my projects. The one downside of this has been that when inspecting the object in a debugger, it's now wrapped by the proxy javascript proxy.

enter image description here

Intead of seeing [[Handler]],[[Target]],[[isRevoked]] I would prefer to just see the object referenced by [[Target]].

It's a minor inconvenience but I think that it could be solved with a Chrome Devtools custom formatter.

Seems like this would be fairly common, but I can't find any existing formatters. Just wanted to double check that there wasn't already one out there before I go down the road of writing my own.

NSjonas
  • 10,693
  • 9
  • 66
  • 92
  • 1
    If you write a formatter, please open an issue on https://github.com/google/webfundamentals and I'll create a doc of community-developed formatters. – Kayce Basques Apr 17 '19 at 21:28
  • 1
    Oh gosh I would *never* want this!!! Loosing the intent of a Proxy in the dev output would give me an aneurysm! I mean if it were really bad fine add a `toString` to the Proxy object. But seriously I don't like the idea of the dev tools hiding things from me even if it means one extra triangle click. – Sukima Nov 18 '19 at 14:49
  • 1
    @Sukima it makes sense for tooling that is adding proxy abstraction layers (EX: mobx). As a consumer of that library, you don't want to have to be concerned with what it is doing behind the scenes. I'm not suggesting that you do this for all proxies. – NSjonas Nov 18 '19 at 19:19

1 Answers1

9

So it turns out this is quite difficult to achieve. The first problem is that it's impossible to identify a Proxy without:

A: Adding a custom symbol to your proxy implementation (if you control the Proxy init code)

B: Overriding the window.Proxy prototype and using a Weakset to basically track every proxy init

On top of that, there is no way to access to original [[Target]] object. However, running JSON.parse(JSON.stringify(obj)) does seems to work well for just console.log purposes.

Assuming you don't have control to modify the Proxy handler, this is what your solution would look like:

// track all proxies in weakset (allows GC)
const proxy_set = new WeakSet();
window.Proxy = new Proxy(Proxy, {
      construct(target, args) {
        const proxy = new target(args[0], args[1]);
        proxy_set.add(proxy);
        return proxy;
      },
});

window.devtoolsFormatters = [{
  header(obj: any) {
    try {
      if (!proxy_set.has(obj)) {
        return null;
      }
      return ['object', {object: JSON.parse(JSON.stringify(obj))}]; //hack... but seems to work
    } catch (e) {
      return null;
    }
},
  hasBody() {
      return false;
  },
}];
NSjonas
  • 10,693
  • 9
  • 66
  • 92