Skip to content

Conversation

@bvaughn
Copy link
Owner

@bvaughn bvaughn commented Jul 13, 2019

  • Auto-append component stack to console.error and console.warn calls.
  • Temporarily disable all console logging before re-running a function component to inspect hooks.
  • Make sure not to double append a stack to any warnings logged by React.
  • Test with multiple renderers First injected renderer wins; console won't be patched for subsequent renderers

Resolves #347

Related React PR facebook/react#16133

Questions

  • Is the zero width space character (added in 6a196fd) reasonable or might it cause problems with any instrumented logging of warnings/errors? This is out of DevTools hands since the component stack formatting is now being injected by React.
  • Is it okay to log owner stacks rather than full component stacks? Seems preferable to me, but it is different from the React official errors/warnings.

Demo

Screen Shot 2019-07-15 at 8 52 59 AM

@bvaughn
Copy link
Owner Author

bvaughn commented Jul 15, 2019

CI is failing because of a Yarn issue, yarnpkg/yarn#7403

@bvaughn
Copy link
Owner Author

bvaughn commented Jul 15, 2019

At this point, the tests are expected to fail until facebook/react#16139 has landed. This dependency has been removed.

@bvaughn bvaughn requested a review from gaearon July 16, 2019 21:26

try {
// $FlowFixMe property error|warn is not writable.
targetConsole[method] = overrideMethod;
Copy link
Collaborator

@gaearon gaearon Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to be aware of is that this might cause the methods to lose location information displayed by the browser. Like when you warn/error and it says "foo.js:XX" in the upper right corner:

Screen Shot 2019-07-16 at 23 02 10

But now it would point inside DevTools.

People might find this very invasive, especially when we're not inside a React component. For example they may have been relying on clicking on those locations in their logs and warnings in the past.

I guess it's kind of unavoidable. Although would be nice to start a conversation with browsers if we can somehow specify to skip the topmost stack level when displaying it.

(We have a similar problem in CRA already because we also override it there.)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree with this as a downside. I will reach out to some folks on Chrome's developer tools team to at least start that conversation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way to mitigate or limit impact from this would be to have DevTools call the Global Hook when it begins or exits the React work loop. Then you could only inject the overrides at that point, and restore them afterwards.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... do you mean the work loop would call a function on the DevTools global hook (or otherwise notify it) any time it started/stopped work?

src/hook.js Outdated
// because Webpack generates JS output that will runtime error with the typeof check.
// e.g. typeof patchConsole === 'function'
// becomes: typeof _backend_console__WEBPACK_IMPORTED_MODULE_0__["patch"] === 'function'
// and _backend_console__WEBPACK_IMPORTED_MODULE_0__ itself is undefined
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it undefined? I don't think I understand this.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a comment in the header about this too, but basically for the browser version- we inject the hook by to-stringing it.

// Inject a `__REACT_DEVTOOLS_GLOBAL_HOOK__` global so that React can detect that the
// devtools are installed (and skip its suggestion to install the devtools).
injectCode(
';(' + installHook.toString() + '(window))' + saveNativeValues + detectReact
);

Because of this, imports won't work- although they will for React Native.

If you have suggestions on the wording I would be happy to clean it up.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a wording improvement.

const ownerName =
owner != null ? getDisplayNameForFiber(owner) : null;

ownerStack += describeComponentFrame(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason we wouldn't prefer to keep this logic in React, and inject a function that gives us a full owner stack instead?

Copy link
Owner Author

@bvaughn bvaughn Jul 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We kind of talked about this 😄Maybe you missed my reply?

facebook/react#16139 (comment)

The relevant bit to this question is:

If React just injected ReactDebugCurrentFrame, then the only thing DevTools could use would be getStackAddendum()- which returns a component stack containing all ancestors, not just parents. By injecting a ref to the current Fiber, DevTools can choose what kind of component stack to generate (currently, owners-only).

I could inject a new method that gives an owners-only stack, or update the old one to accept a parameter- but I think it's kind of nice for DevTools to have a little more control over this in case we decide to change it later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, what I suggested is to add this owner-only function to ReactDebugCurrentFrame. :-) But fair enough.

@bvaughn
Copy link
Owner Author

bvaughn commented Jul 17, 2019

I'm going to go ahead and make this a configurable preference, at least for now. It seems pretty invasive and might turn out to be annoying in ways I haven't accounted for.

toggle-component-stacks-Kapture 2019-07-17 at 9 19 17

@bvaughn
Copy link
Owner Author

bvaughn commented Jul 17, 2019

I'm going to roll forward with this, since there didn't seem to be any strong concerns (just questions). Please feel free to follow up with me if there are concerns though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-append component stack to error logs

3 participants