Jamesllllllllll / beacons-link-checker

Check if you have broken links on your Beacons page
https://beacons-link-checker.vercel.app
3 stars 2 forks source link

Serverless function - Puppeteer / Chromium #2

Closed Jamesllllllllll closed 10 months ago

Jamesllllllllll commented 10 months ago

I tested this serverless function in another Next project that uses the Pages router.

It is working and returns the expected data when submitting a Beacons username.

However, the same UI & serverless function returns the error below in the terminal for this commit https://github.com/Jamesllllllllll/beacons-link-checker/commit/5fa7a7f52d0327dca121b9c3c3d37c4e1c8bb534

I think it is an issue with the AppRouter, so I will be working on layout.js to look for a solution.

- wait compiling /_error (client and server)...
- event compiled client and server successfully in 1006 ms (170 modules)
- wait compiling /page (client and server)...
- event compiled client and server successfully in 3.7s (1426 modules)
- wait compiling...
- event compiled successfully in 336 ms (810 modules)
- wait compiling /api/checkBeacon (client and server)...
- event compiled successfully in 509 ms (619 modules)
Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
    at AppContainer (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:323:29)
    at AppContainerWithIsomorphicFiberStructure (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:359:57)
    at div
    at Body (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:659:21)
Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
    at AppContainer (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:323:29)
    at AppContainerWithIsomorphicFiberStructure (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:359:57)
    at div
    at Body (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:659:21)
Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
    at PathnameContextProviderAdapter (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\shared\lib\router\adapters.js:84:11)
    at AppContainer (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:323:29)
    at AppContainerWithIsomorphicFiberStructure (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:359:57)
    at div
    at Body (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:659:21)
Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
    at PathnameContextProviderAdapter (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\shared\lib\router\adapters.js:84:11)
    at AppContainer (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:323:29)
    at AppContainerWithIsomorphicFiberStructure (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:359:57)
    at div
    at Body (C:\Users\james\Documents\Projects\Side Projects\beacons-link-checker\node_modules\next\dist\server\render.js:659:21)

The exact same code produces this result in another Next project using the Pages router:

Beacon Success

Jamesllllllllll commented 10 months ago

Ok - It was the App Router's method of API calls.

With the Pages Router, you can create a function at /api/myFunction.js and fetch('/api/myFunction?myParam=${param}')

The function is a default export like so:

export default async function handler(req, res) { ...

The default method is GET, and you can declare otherwise in the handler.


However, in the App router you need to structure the files like /api/myFunction/route.js and export named functions for the request method like so:

export async function GET(req, res) { ...


I got it to work locally and deployed it to development preview on Vercel.

Now there is an issue with opening Chromium. This makes me wonder - is it even possible to run Puppeteer/Chromium on the deployed Node runtime??

Here are the logs from Vercel:

checkBeacon running...
Username: api
URL: https://beacons.ai/api
Opening the browser......
Could not create a browser instance => :  Error: Could not find Chrome (ver. 116.0.5845.96). This can occur if either
 1. you did not perform an installation before running the script (e.g. `npm install`) or
 2. your cache path is incorrectly configured (which is: /home/sbx_user1051/.cache/puppeteer).
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.
    at ChromeLauncher.resolveExecutablePath (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ProductLauncher.js:300:27)
    at ChromeLauncher.executablePath (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ChromeLauncher.js:180:25)
    at ChromeLauncher.computeLaunchArguments (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ChromeLauncher.js:97:37)
    at async ChromeLauncher.launch (/var/task/node_modules/puppeteer-core/lib/cjs/puppeteer/node/ProductLauncher.js:79:28)
Jamesllllllllll commented 10 months ago

Chromium is too large for it to be used in a Vercel serverless function.

I've tried using the playwright-core and chrome-aws-lambda packages referenced by a few tutorials like this one, and I'm encountering a Webpack loader problem like this one.

The above issue links to this solution, but I didn't have target: serverless in next.config.js. Going to take a break from this for the night!

Jamesllllllllll commented 10 months ago

Found a solution that reduces chrome-aws-lambda bundle size by going with a smaller version. Still, the function is <1MB away from max.

Edit: Nevermind! This version does not work with Node v18

Continuing the journey here: https://www.stefanjudis.com/blog/how-to-use-headless-chrome-in-serverless-functions/

Jamesllllllllll commented 10 months ago

The serverless function was reaching the 10sec limit for Vercel hobby plans, so I got a free Pro trial - it takes 20-25 seconds to fire up the headless Chromium browser, navigate to the page and read the contents (yikes!)

I added the link checking functionality as well.

The UI ain't pretty yet, but it's working!

https://beacons-link-checker-git-development-jamesllllllllll-s-team.vercel.app/