Skip to content

[DevTools Bug]: Hook names fail to parse if source file for Component is an html file #22319

Open

Description

@jstejada

When testing our fixture in Safari (./fixtures/devtools/standalone/index.html) with the standalone build if DevTools, I noticed that we were unable to parse hook names because the source file where the components are defined isn't a JavaScript file, and instead an HTML file (as in index.html), which contains HTML code, and some JS inside script tags, so the babel parser fails to parse the file.

Specifically:

// parseSourceAndMetadata.js

const originalSourceAST = withSyncPerfMeasurements(
  '[@babel/parser] parse(originalSourceCode)',
  () =>
    parse(originalSourceCode, {
      sourceType: 'unambiguous',
      plugins: ['jsx', plugin],
    }),
);

In the above code, the call to parse fails because originalSourceCode is actually html (with JS inside) like:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>TODO List</title>

    <!-- ... -->

  <body>
    <div id="root"></div>
    <script type="text/javascript">
      const { useState } = React;

      function App() {
        const [count, setCount] = useState(0);
        return null;
      }

      ReactDOM.render(React.createElement(App), document.getElementById("root"));
    </script>
  </body>

And parse expects actual JS code.

DevTools should handle the case when source files aren't JS files, and still be able to extract out the hook names, or fail more gracefully. As of #22320, we log to the console a slightly better error message when this happens, as opposed to an obscure parsing error.

Repro steps

  1. Run standalone app
  2. Open fixtures file in safari: ./fixtures/devtools/standalone/index.html
  3. Try getting hook names, observe that parsing source files fails

Activity

  1. self-assigned this
    on Sep 14, 2021
  2. bvaughn commented on Sep 15, 2021

    @bvaughn
    Contributor

    I think the title of this issue might be misleading. (I might be wrong but) I don't think the cause is an inline <script type="text/javascript"> tag but rather the fact that our demo uses <script type="text/babel"> which has non-standard JS syntax (JSX) that requires a special plug-in to parse.

    We could look into how much weight this additional plug-in would add to the bundle, but initially I lean towards saying that should just explicitly not support JSX syntax.

    Again though, I could be wrong and maybe it really is the inline tag part. 😄

  3. changed the title [-][DevTools Bug]: Hook names fail to parse if source JS is defined in an htm file with inline script tags[/-] [+][DevTools Bug]: Hook names fail to parse if source JS is defined in an html file with inline script tags[/+] on Sep 15, 2021
  4. changed the title [-][DevTools Bug]: Hook names fail to parse if source JS is defined in an html file with inline script tags[/-] [+][DevTools Bug]: Hook names fail to parse if source file for javascript is an html file[/+] on Sep 15, 2021
  5. jstejada commented on Sep 15, 2021

    @jstejada
    ContributorAuthor

    @bvaughn so i tested this by making the index.html file only contain a regular "text/javascript" script tag, without jsx or anything:

    image

    and our call to babel.parse() still fails for parse the file, I presume because parse() expects the input to be JS , but we are passing html, so it fails to parse the html outside the script tags.

    not sure what the best approach would be here, maybe try to extract the JS from script tags if we detect that the source file is an html file?

  6. changed the title [-][DevTools Bug]: Hook names fail to parse if source file for javascript is an html file[/-] [+][DevTools Bug]: Hook names fail to parse if source file for Component is an html file[/+] on Sep 15, 2021
  7. bvaughn commented on Sep 15, 2021

    @bvaughn
    Contributor

    The "HTML" you're referring to above is also JSX :)

    React.createElement('div', {id: 'root'}; // <div id="root"
  8. jstejada commented on Sep 15, 2021

    @jstejada
    ContributorAuthor

    we discussed offline and there was confusion about what I was referring to in this issue. I updated the summary to try to clarify the problem.

  9. bvaughn commented on Nov 4, 2021

    @bvaughn
    Contributor

    As of #22320, we log to the console a slightly better error message when this happens, as opposed to an obscure parsing error

    For added context, the error I'm seeing in the console is:

    Error: Hook source code location not found.
        at u (hookNamesCache.js:215)
        at loadSourceAndMetadata.js:435
    

    This happens before the parsing step. I wonder what has changed since you originally posted this?


    Digging in further, that's because hookSource is missing a file name, e.g.:

    hookSource: {
      columnNumber: 22,
      fileName: undefined,
      functionName: "ListItem",
      lineNumber: 131,
    }

    Looking at the error-stack-parser source, it seems like an undefined fileName indicates a stack frame of either "eval" or "<anonymous>". Sure enough, looking at the Error stack for one of our components defined in an HTML file like this, I see e.g. " at ListItem (<anonymous>:135:22)".

    I'm not sure if there's much we can do about this.


    I'm seeing this same behavior (an undefined fileName) when using both Chrome and Safari.

  10. akgupta0777 commented on Dec 4, 2021

    @akgupta0777
    Contributor

    This seems easy to fix, Maybe I can fix this.
    @bvaughn or @jstejada
    Any other information or guidance you wanna give for a headstart.

    Also, I want to know about how hook name parsing is done in react devtools. Any resources for that will be great for me.

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions