Bhavesh Kadiya
Bhavesh Kadiya

Reputation: 7

Puppeteer script does nothing in NodeJS

I tried to install Puppeteer in a fresh NodeJS project. When I tried to launch a browser and take a screenshot it did not work.

I did:

  1. make new directory
  2. in terminal npm init -y
  3. create file index.js
  4. install puppeteer npm i puppeteer
  5. write this code in index.js:
    import * as puppeteer from 'puppeteer';
    
    (async ()=> {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('https://github.com/puppeteer/puppeteer');
        await page.screenshot({path: 'my.png'});
        // await browser.close();
    });
    
  6. run with node index.js

It neither opens the browser nor creates the screenshot.

Upvotes: 0

Views: 267

Answers (1)

ggorlen
ggorlen

Reputation: 56993

You need () after your IIFE: }); should be })();. Otherwise, the function is defined but is never executed.

A good way to debug this is to add a sanity check console.log("running") at the top of the IIFE. If that doesn't run, but another sanity check console.log("running") outside the IIFE does, you've discovered that the function was never called.

Note that you're running headlessly, so after you fix the IIFE issue, it's still expected behavior that no visible browser will open. The expected behavior for your script is that it'll run, create a screenshot, and then hang forever because browser.close() is commented out, requiring you to press Ctrl+c to terminate it. Use browser.launch({headless: false}) if you want to see a browser open.

I suggest the following Puppeteer boilerplate:

const puppeteer = require("puppeteer"); // module import is fine too

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();

  // your page code

})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

This is optimal for a number of reasons, major and minor:

  1. If the script throws an error while working with a page, the browser will be closed so the script can exit cleanly. Otherwise, it'll hang forever, leaking a process.
  2. All errors are caught and logged, avoiding an uncaught promise rejection warning.
  3. Errors encountered launching the browser are also caught.
  4. No unnecessary pages are created, since Puppeteer starts with a page already open.
  5. It's flat, so there's no try/catch layer required for most scripts.

In Node 20+ you can use top-level await in a module and avoid the IIFE. try/catch is useful in that case.

Upvotes: 3

Related Questions