Search code examples
javascriptgoogle-chrome-devtools

Chrome Devtools formatter for javascript proxy


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.


Solution

  • 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;
      },
    }];