Search code examples
javascriptnode.jsexpresspolymerpuppeteer

Polymer Starter Kit with Node, Express, and Puppeteer


Okay, I'm a newbie to all this so any help greatly appreciated.

I've managed to use Node and Express to serve up Polymer Starter Kit (PSK) website from the Polymer build directory from a file I created in the home directory (server.js):

// Node.js notation for importing packages
var express = require('express');

// Spin up a server
var app = express();

// Serve static files from the main build directory
app.use(express.static(__dirname + '/build/es5-bundled'));

// Render index.html on the main page, specify the root
app.get('/', function(req, res){
  res.sendFile("index.html", {root: '.'});
});

// Tell the app to listen for requests on port 3000
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

From the terminal I type 'node server.js' and the website is available on localhost 3000 and all is well.

What I want to do is use a node module, Puppeteer, to generate a PDF file from a sample webpage when the website visitor clicks a button. Here's the code I put into the MyApp class of the my-app.html file of the PSK that is called when a button is clicked.

functionPDFCreate() {

  const puppeteer = require('puppeteer');

  (async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://news.ycombinator.com', { waitUntil: 'networkidle2' });
    await page.pdf({ path: 'hn.pdf', format: 'A4' });

    await browser.close();
  })();

}

However, the function above returns 'require is not defined'. Am I doing things wrong? Do I need need to somehow put the functionPDFCreate code into server.js and use Express routing? How on earth do I execute the code in functionPDFCreate when a PSK website visitor clicks a button? Thanks for any help you can offer.


Solution

  • Are you invoking functionPDFCreate in a browser context? It's not going to work even with browserify or webpack as @YouneL suggested.

    You should expose endpoint in express app serving your PDF:

    app.get('/hn', function(req, res) {
        functionPDFCreate().then(() => {
            // now file is written on the disk
            res.sendFile('hn.pdf', { root: '.' });
        });
    });
    

    functionPDFCreate should look like this:

    const puppeteer = require('puppeteer');
    
    async function functionPDFCreate() {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('https://news.ycombinator.com', { waitUntil: 'networkidle2' });
        await page.pdf({ path: 'hn.pdf', format: 'A4' });
    
        await browser.close();
    }
    

    In your browser app, you should have download button like this (framework agnostic example):

    <a href="http://localhost:3000/hn" download="hn.pdf">Download HN PDF</a>