Hooks are the preferred way for writing stateful React components, but there are a few things about them that still lag behind the class component API: inspecting state in DevTools (since hooks aren’t “named”). Even now that this feature has been released, it remains disabled by default because the size of DEV bundles in larger apps (e.g. Facebook) makes parsing the AST very slow.

To alleviate this, we plan to provide an additional compilation tool that adds hook names to an extended source map during build time (#21782). However not every application will use this and so DevTools will still need to fall back to parsing source into an AST.

Currently this is done using the '@babel/parser' package on the main thread:
https://github.com/facebook/react/blob/c2c6ea1fdead7a33a33664675365b1575315276e/packages/react-devtools-extensions/src/parseHookNames.js#L536-L540

It would be nice to move this into a worker so that DevTools remains responsive even when parsing large sources.

---

One downside of using a worker for this is that serializing data to share between the worker and main thread (e.g. the source code string or the AST itself) could be expensive. This change will probably also require redesigning the boundaries a bit to reduce the number and size of things passed between boundaries. For example, the main thread could pass the URL of the source code to the worker, which could fetch and parse the file. Then the main thread could pass line/column information and the worker could return a hook name (or null). The goal would be to avoid having to serialize large AST structures.
]);
  });
  it('should return null for custom hooks without explicit names', async () => {
    const Component = require('./__source__/__untransformed__/ComponentWithUnnamedCustomHooks')
      .Component;
    const hookNames = await getHookNamesForComponent(Component);
    expectHookNamesToEqual(hookNames, [
      null, 
      null, 
    ]);
  });
  
  
  describe('inline, external and bundle source maps', () => {
    it('should work for simple components', async () => {
      async function test(path, name = 'Component') {
        const Component = require(path)[name];
        const hookNames = await getHookNamesForComponent(Component);
        expectHookNamesToEqual(hookNames, [
          'count', 
        ]);
      }
      await test('./__source__/Example'); 
      await test('./__source__/__compiled__/inline/Example'); 
      await test('./__source__/__compiled__/external/Example'); 
      await test('./__source__/__compiled__/bundle/index', 'Example'); 
      await test('./__source__/__compiled__/no-columns/Example'); 
    });
    it('should work with more complex files and components', async () => {
      async function test(path, name = undefined) {