puppeteer icon indicating copy to clipboard operation
puppeteer copied to clipboard

[Bug]: crash on PDF render

Open VagrantAI-c opened this issue 3 years ago • 7 comments

Bug description

Steps to reproduce the problem:

  1. clone https://github.com/VagrantAI-c/Puppeteer-pdf-render-repro
  2. run npm ci
  3. run npm run build
  4. run npm run serve

Reproduce from scratch:

import { launch } from 'puppeteer';

(async () => {
  const browser = await launch({
    headless: true,
    args: [
      '--disable-gpu',
      '--disable-dev-shm-usage',
      '--disable-setuid-sandbox',
      '--no-sandbox',
    ],
  });
  const page = await browser.newPage();
  const content = '<!doctype html><html lang="en"><head></head><body><h1>Test</h1></body></html>';
  await page.setContent(content, { waitUntil: 'networkidle0' });
  await page.pdf({ format: 'a4' });
  await page.close();
})();

This error is happening on https://github.com/puppeteer/puppeteer/blob/ce0dd25349b3141409cf68121a2bf9a770d9ecf7/src/common/util.ts#L387 while running await page.pdf({ format: 'a4' });

Puppeteer version

14.4.0

Node.js version

18.3.0

npm version

8.11.0

What operating system are you seeing the problem on?

Windows

Relevant log output

\dist\main.js:3113
    return new Readable({
           ^

TypeError: Readable is not a constructor
    at Object.getReadableFromProtocolStream (\dist\main.js:3113:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Page.pdf (\dist\main.js:6019:26)
    at async \dist\main.js:35011:5

VagrantAI-c avatar Jun 16 '22 07:06 VagrantAI-c

I am not sure exactly why but webpack does not seem to process the dynamic import correctly. Instead of returning the default export, it returns an object that includes {default: StreamModule}. I am not very familiar with webpack but perhaps it could be solved by fixing the configuration?

OrKoN avatar Jun 24 '22 10:06 OrKoN

It also might be involved with Typescript configuration. I don't know if there's a correct or incorrect config: Puppeteer doesn't provide working solutions and examples with bundlers, so I believe any config should be fine by default. Moreover, this config produces correct and working output at [email protected]

VagrantAI-c avatar Jun 24 '22 10:06 VagrantAI-c

Yeah, we don't officially support bundlers (e.g., we don't run tests with them) but we also try to fix issues whenever possible. We made changes to TypeScript configs to support ESM alongside CJS so perhaps it caused it but it's hard to say where exactly the problem is. Which build output (esm or cjs) does webpack use in your example?

OrKoN avatar Jun 24 '22 10:06 OrKoN

I don't know exactly, but I tried some experiments on Typescript module option: changing it from es2022 to nodenext/node16 helps, but I can't tell exactly why.

VagrantAI-c avatar Jun 24 '22 11:06 VagrantAI-c

perhaps @jrandolf has an idea! Great that there is a workaround.

OrKoN avatar Jun 24 '22 11:06 OrKoN

I am seeing this same error in version 14.4.1; downgrading to 13.7.0 resolved it for me.

sonrai-samroutledge avatar Jun 30 '22 15:06 sonrai-samroutledge

I am having the same issue.

imtanmoy avatar Jul 28 '22 10:07 imtanmoy

I have also run into this issue. It occurs when webpack (v5 on my end) bundles puppeteer. I have solved it by explicitly declaring webpack ignore directive when importing a file which uses puppeteer. I did this via dynamic es import, but a static one could be done in a very similar way:

const loadModule = async (modulePath) => {
  try {
    return await import(/* webpackIgnore: true */ modulePath)
  } catch (e) {
    throw new ImportError(`Unable to import module ${modulePath}`)
  }
}

const renderPdf = (await loadModule('../../renderPdf/index.js')).default

pjg avatar Aug 13 '22 16:08 pjg

This is not an issue with puppeteer at all, but with webpack by itself.

A fresh minimal webpack repo with the following code also throws for the same reason:

async function handler() {
  const { Readable } = await import('node:stream');
  assert(typeof Readable !== 'undefined', 'Readable is undefined.');
}

void handler();

See: https://github.com/webpack/webpack/issues/16757

rdsedmundo avatar Feb 24 '23 18:02 rdsedmundo

Definitely a webpack problem, not a puppeteer one.

Moved my bundling to esbuild and it worked first time.

DynamicArray avatar May 08 '23 22:05 DynamicArray

Closing based on previous comments

OrKoN avatar May 09 '23 05:05 OrKoN

I was able to work around this by using createRequire to load the cjs output instead of esm.

Change this import:

import puppeteer from 'puppeteer-core'

to this:

import { createRequire } from 'module'

const require = createRequire(import.meta.url)
const puppeteer = require('puppeteer-core')

I'm guessing this has to do with using "type": "module" in my package.json file and "moduleResolution": "nodenext" in my tsconfig.json file. I've run into a handful of similar issues with other libraries, like https://github.com/vercel/next.js/issues/46078

michaelhays avatar Aug 21 '23 20:08 michaelhays

  • TL;DR

    const puppeteer = require('puppeteer');
    
  • Reference https://github.com/webpack/webpack/issues/16757#issuecomment-1851590537

bradwoo8621 avatar Dec 12 '23 09:12 bradwoo8621