title: Flow type definitions for Puppeteer prevent using default export?
body: <p>Consider puppeteer's <code>launch()</code> method. The <a href="https://github.com/GoogleChrome/puppeteer#usage" rel="noreferrer">usage guidelines in the Puppeteer readme</a> recommend to use <code>const puppeteer = require('puppeteer')</code> and then <code>puppeteer.launch()</code>:</p>
  
  <blockquote>
  <pre><code>const puppeteer = require('puppeteer');
  
  (async () =&gt; {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await page.screenshot({path: 'example.png'});
  
    await browser.close();
  })();
  </code></pre>
  </blockquote>
  
  <p>And Puppeteer itself <a href="https://github.com/GoogleChrome/puppeteer/blob/cba0f98a2ac7edd3c2bffd0ac53185877403da6b/index.js#L40" rel="noreferrer">exports an instance</a>, which seems to further confirm the default export is meant to be used:</p>
  
  <blockquote>
  <pre><code>module.exports = new Puppeteer(__dirname, preferredRevision, isPuppeteerCore);
  </code></pre>
  </blockquote>
  
  <p>However, the <a href="https://github.com/flow-typed/flow-typed/blob/e24d577ea33b4193b012231820c152d4f15535d7/definitions/npm/puppeteer_v1.12.x/flow_v0.104.x-/puppeteer_v1.12.x.js" rel="noreferrer">Flow type definitions for puppeteer ≥1.12</a> use <code>declare export function launch()</code> and <strong>don't</strong> include a default export, so <strong>Flow requires me to write <code>import { launch } from "puppeteer"</code></strong> instead of <code>import puppeteer from "puppeteer"</code>.</p>
  
  <p><strong>But using the named import yields <code>TypeError: Cannot read property '_launcher' of undefined</code>.</strong> Similarly, we can confirm this doesn't work with a simple test (Node v10.15.0, puppeteer 1.19.0):</p>
  
  <pre><code>const puppeteer = require("puppeteer");
  puppeteer.launch();  // works
  </code></pre>
  
  <pre><code>const { launch } = require("puppeteer");
  launch();  // TypeError: Cannot read property '_launcher' of undefined
  </code></pre>
  
  <p>(Presumably this is because <code>const { launch } =</code> gives me an unbound method — <code>this === undefined</code> when called.)</p>
  
  <hr>
  
  <p><strong>Attempt 2</strong>: In Flow you can also use a <strong>namespaced import</strong> <code>import * as puppeteer from "puppeteer"</code>, but <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" rel="noreferrer">it seems</a> this explicitly forgoes access to the default export, instead yielding <code>TypeError: puppeteer.launch is not a function</code>.</p>
  
  <p>(I'm less familiar with TypeScript, but the <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/puppeteer/index.d.ts" rel="noreferrer">DefinitelyTyped defs for Puppeteer</a> also use <code>export function launch()</code> rather than a default export. That said, <a href="https://www.lewuathe.com/using-puppeteer-in-typescript.html" rel="noreferrer">they seem intended</a> to be used with <code>import * as puppeteer from "puppeteer"</code>, although I'm not sure why this would work when it doesn't in Flow; perhaps a difference in how TypeScript handles ES6 modules?)</p>
  
  <hr>
  
  <p>So, am I holding it wrong, or are the Flow type definitions wrong? (In which case, how has nobody else encountered this problem?)</p>