delucis / astro-og-canvas

Generate OpenGraph images for your Astro site
159 stars 18 forks source link

[Feature request]: Support @astrojs/cloudflare SRR Adapter #35

Open RodrigoTomeES opened 11 months ago

RodrigoTomeES commented 11 months ago

Hi,

This package is awesome!! But it is incompatible with @astrojs/cloudflare SRR Adapter. When you deploy it I recieve this error:

In cloudflare

16:57:36.710 | ✘ [ERROR] Could not resolve "node:fs/promises"
-- | --
16:57:36.710 |  
16:57:36.710 | dist/$server_build/chunks/pages/__73e63732.mjs:2:15:
16:57:36.710 | 2 │ import fs from 'node:fs/promises';
16:57:36.710 | ╵                ~~~~~~~~~~~~~~~~~~
16:57:36.711 |  
16:57:36.711 | The package "node:fs/promises" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
16:57:36.711 |  
16:57:36.711 | ✘ [ERROR] Could not resolve "node:module"
16:57:36.711 |  
16:57:36.711 | dist/$server_build/chunks/pages/__73e63732.mjs:6:30:
16:57:36.711 | 6 │ import { createRequire } from 'node:module';
16:57:36.711 | ╵                               ~~~~~~~~~~~~~
16:57:36.712 |  
16:57:36.712 | The package "node:module" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
16:57:36.712 |  
16:57:36.719 | ✘ [ERROR] Could not resolve "crypto"
16:57:36.719 |  
16:57:36.720 | node_modules/deterministic-object-hash/dist/index.js:7:25:
16:57:36.720 | 7 │ const crypto_1 = require("crypto");
16:57:36.720 | ╵                          ~~~~~~~~
16:57:36.720 |  
16:57:36.720 | The package "crypto" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
16:57:36.720 |  
16:57:36.739 | ✘ [ERROR] Could not resolve "path"
16:57:36.740 |  
16:57:36.740 | node_modules/canvaskit-wasm/bin/canvaskit.js:153:20:
16:57:36.740 | 153 │ if(za)Aa=ya?require("path").dirname(Aa)+"/":__dirname+"/",Fa=()=>...
16:57:36.740 | ╵                     ~~~~~~
16:57:36.740 |  
16:57:36.741 | The package "path" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
16:57:36.741 |  
16:57:36.741 | ✘ [ERROR] Could not resolve "fs"
16:57:36.741 |  
16:57:36.741 | node_modules/canvaskit-wasm/bin/canvaskit.js:153:82:
16:57:36.741 | 153 │ ...+"/",Fa=()=>{Ea\|\|(fs=require("fs"),Ea=require("path"))},Ba=fun...
16:57:36.742 | ╵                                 ~~~~
16:57:36.742 |  
16:57:36.742 | The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
16:57:36.742 |  
16:57:37.099 | error   Could not resolve "node:fs/promises"
16:57:37.099 | File:
16:57:37.100 | dist/$server_build/chunks/pages/__73e63732.mjs:2:15
16:57:37.100 | Code:
16:57:37.100 | 1 \| import { deterministicString } from 'deterministic-object-hash';
16:57:37.100 | > 2 \| import fs from 'node:fs/promises';
16:57:37.101 | \|               ^
16:57:37.101 | 3 \| import path from 'node:path';
16:57:37.101 | 4 \| import { _ as __vite_glob_0_0 } from '../prerender_6a77773e.mjs';
16:57:37.101 | 5 \| import init from 'canvaskit-wasm';
16:57:37.101 | Stacktrace:
16:57:37.101 | Error: Build failed with 5 errors:
16:57:37.102 | dist/$server_build/chunks/pages/__73e63732.mjs:2:15: ERROR: Could not resolve "node:fs/promises"
16:57:37.102 | dist/$server_build/chunks/pages/__73e63732.mjs:6:30: ERROR: Could not resolve "node:module"
16:57:37.102 | node_modules/canvaskit-wasm/bin/canvaskit.js:153:20: ERROR: Could not resolve "path"
16:57:37.102 | node_modules/canvaskit-wasm/bin/canvaskit.js:153:82: ERROR: Could not resolve "fs"
16:57:37.102 | node_modules/deterministic-object-hash/dist/index.js:7:25: ERROR: Could not resolve "crypto"
16:57:37.102 | at failureErrorWithLog (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:1650:15)
16:57:37.102 | at /opt/buildhome/repo/node_modules/esbuild/lib/main.js:1059:25
16:57:37.103 | at /opt/buildhome/repo/node_modules/esbuild/lib/main.js:1004:52
16:57:37.103 | at buildResponseToResult (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:1057:7)
16:57:37.103 | at /opt/buildhome/repo/node_modules/esbuild/lib/main.js:1086:16
16:57:37.103 | at responseCallbacks.<computed> (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:703:9)
16:57:37.103 | at handleIncomingPacket (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:763:9)
16:57:37.103 | at Socket.readFromStdout (/opt/buildhome/repo/node_modules/esbuild/lib/main.js:679:7)
16:57:37.103 | at Socket.emit (node:events:514:28)
16:57:37.104 | at addChunk (node:internal/streams/readable:324:12)
16:57:37.104 |  
16:57:37.128 | Failed: Error while executing user command. Exited with error code: 1
16:57:37.137 | Failed: build command exited with code: 1
16:57:38.184 | Failed: error occurred while running build command

In local build

X [ERROR] Could not resolve "node:fs/promises"

    dist/$server_build/chunks/pages/__b54f80a9.mjs:2:15:
      2 │ import fs from 'node:fs/promises';
        ╵                ~~~~~~~~~~~~~~~~~~

  The package "node:fs/promises" wasn't found on the file system but is built into node. Are you
  trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this
  error.

X [ERROR] Could not resolve "node:module"

    dist/$server_build/chunks/pages/__b54f80a9.mjs:6:30:
      6 │ import { createRequire } from 'node:module';
        ╵                               ~~~~~~~~~~~~~

  The package "node:module" wasn't found on the file system but is built into node. Are you trying
  to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

X [ERROR] Could not resolve "crypto"

    node_modules/deterministic-object-hash/dist/index.js:7:25:
      7 │ const crypto_1 = require("crypto");
        ╵                          ~~~~~~~~

  The package "crypto" wasn't found on the file system but is built into node. Are you trying to
  bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

X [ERROR] Could not resolve "path"

    node_modules/canvaskit-wasm/bin/canvaskit.js:153:20:
      153 │ if(za)Aa=ya?require("path").dirname(Aa)+"/":__dirname+"/",Fa=()=>{Ea||(fs=require("fs"),Ea=require("... 
          ╵                     ~~~~~~

  The package "path" wasn't found on the file system but is built into node. Are you trying to
  bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

X [ERROR] Could not resolve "fs"

    node_modules/canvaskit-wasm/bin/canvaskit.js:153:82:
      153 │ ...(Aa)+"/":__dirname+"/",Fa=()=>{Ea||(fs=require("fs"),Ea=require("path"))},Ba=function(a,b){Fa();a... 
          ╵                                                   ~~~~

  The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle
  for node? You can use "platform: 'node'" to do that, which will remove this error.

 error   Could not resolve "node:fs/promises"
dist/$server_build/chunks/pages/__b54f80a9.mjs:6:30: ERROR: Could not resolve "node:module"
node_modules/canvaskit-wasm/bin/canvaskit.js:153:20: ERROR: Could not resolve "path"
node_modules/canvaskit-wasm/bin/canvaskit.js:153:82: ERROR: Could not resolve "fs"
node_modules/deterministic-object-hash/dist/index.js:7:25: ERROR: Could not resolve "crypto"
    at failureErrorWithLog (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1650:15)
    at E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1059:25
    at E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1004:52
    at buildResponseToResult (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1057:7)
    at E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1086:16
    at responseCallbacks.<computed> (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:703:9)
    at handleIncomingPacket (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:763:9)
    at Socket.readFromStdout (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:679:7)
    at Socket.emit (node:events:514:28)
    at addChunk (node:internal/streams/readable:376:12)

It's seem like the package has a lot of code depending of node 🤔

List of dependencies that requiere a node enviroment:

RodrigoTomeES commented 11 months ago

deterministic-object-hash released the version 2.0.1 so now it's compatible with web workers!

RodrigoTomeES commented 11 months ago

With the new version cryto error it's fixed. Now the errors are:

X [ERROR] Could not resolve "path"

    dist/$server_build/chunks/pages/__30458630.mjs:2:25:
      2 │ import require$$0$1 from 'path';
        ╵                          ~~~~~~

  The package "path" wasn't found on the file system but is built into node. Are you trying to
  bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

X [ERROR] Could not resolve "fs"

    dist/$server_build/chunks/pages/__30458630.mjs:3:23:
      3 │ import require$$1 from 'fs';
        ╵                        ~~~~

  The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle
  for node? You can use "platform: 'node'" to do that, which will remove this error.

X [ERROR] Could not resolve "node:fs/promises"

    dist/$server_build/chunks/pages/__30458630.mjs:4:15:
      4 │ import fs from 'node:fs/promises';
        ╵                ~~~~~~~~~~~~~~~~~~

  The package "node:fs/promises" wasn't found on the file system but is built into node. Are you
  trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this
  error.

X [ERROR] Could not resolve "node:module"

    dist/$server_build/chunks/pages/__30458630.mjs:7:30:
      7 │ import { createRequire } from 'node:module';
        ╵                               ~~~~~~~~~~~~~

  The package "node:module" wasn't found on the file system but is built into node. Are you trying
  to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

 error   Could not resolve "path"
  File:
    dist/$server_build/chunks/pages/__30458630.mjs:2:25
  Code:
    1649 |   }).join("");
    > 1650 |   let error = new Error(text);
           |               ^
      1651 |   for (const [key, value] of [["errors", errors], ["warnings", warnings]]) {
      1652 |     Object.defineProperty(error, key, {
      1653 |       configurable: true,
  Stacktrace:
Error: Build failed with 4 errors:
dist/$server_build/chunks/pages/__30458630.mjs:2:25: ERROR: Could not resolve "path"
dist/$server_build/chunks/pages/__30458630.mjs:3:23: ERROR: Could not resolve "fs"
dist/$server_build/chunks/pages/__30458630.mjs:4:15: ERROR: Could not resolve "node:fs/promises"
dist/$server_build/chunks/pages/__30458630.mjs:7:30: ERROR: Could not resolve "node:module"
    at failureErrorWithLog (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1650:15)
    at E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1059:25
    at E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1004:52
    at buildResponseToResult (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1057:7)
    at E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:1086:16
    at responseCallbacks.<computed> (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:703:9)
    at handleIncomingPacket (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:763:9)
    at Socket.readFromStdout (E:\Datos\Sites\Projects\rodrigotome.es\node_modules\esbuild\lib\main.js:679:7)
    at Socket.emit (node:events:514:28)
    at addChunk (node:internal/streams/readable:376:12)
delucis commented 11 months ago

Thanks for the update @RodrigoTomeES! Yeah, we’d need to figure out a way to load things without relying on Node’s filesystem APIs. I’m not super experienced in debugging for these serverless environments and there’s some annoying corners here, like how to load the WASM for canvaskit. Hopefully someone else has some good ideas!

RodrigoTomeES commented 11 months ago

Hi @delucis I think this issue is similar https://github.com/withastro/astro/issues/6529 I checked it yesterday but I don't understand how they implemented. I think they include the node libraries 🤔

alexanderniebuhr commented 11 months ago

Once I have some bandwidth, I promised @delucis to debug this. But I don't have any timing, yet.

RodrigoTomeES commented 10 months ago

@alexanderniebuhr could you take a look at the problem?

alexanderniebuhr commented 10 months ago

@RodrigoTomeES I'll take a look, once I have bandwidth for it, not sure if it's this week.

RodrigoTomeES commented 8 months ago

Hi!, @alexanderniebuhr could you take a look at it? 😄

alexanderniebuhr commented 8 months ago

Yeah I looked at this. The issue is we need to refactor this completely to not rely on file system APIs anymore, or at least make sure it doesn't get bundled, if this integration could be doing build time operations only. Those two things are not trivial, so we kinda need to first decide how to move forward

cc @delucis

delucis commented 8 months ago

@alexanderniebuhr I would love some guidance here on architectures that could work. Avoiding FS calls for images and fonts could be possible by requiring users to import and pass them potentially (although I'm not 100% sure how that would work for fonts). I'm not sure about the loading of wasm that is inside our canvaskit dependency.

I did try over the Christmas holidays whether I could refactor to a style more like Astro's image services. It's more complex (and a breaking change) but I did get some of it working. Not sure that necessarily would help — it was actually creating an endpoint that rendered images on demand in SSR that worked in Node but I guess might have the same issues on Cloudflare?

alexanderniebuhr commented 8 months ago

The open question for me is, do we need to load images from file tree runtime or build time?

delucis commented 8 months ago

I think it’s fairly safe to assume people aren’t using this in SSR currently as the fs stuff would probably break in any SSR set-up (even if Node supports fs the file paths would be wrong). At most, someone might have this on a prerendered route.

So that means it’s up to us what a future version that supports SSR would look like. My assumption is we’d need a way to get runtime access to an image to support full on-demand SSR just like you would with Astro’s assets support. But we can impose restrictions like that does to e.g. import an image so we get a resolved path to it etc.

alexanderniebuhr commented 8 months ago

Ok SSR support is wanted.. I can't promise anything, but I'll take a session to find some smart way which works on all runtimes :)

itsmatteomanf commented 5 months ago

I'd definitely love to see this!

I currently use it in a component that injects the OG image link in the head and writes it to a custom path... I didn't very much like a separate route as I wanted to have some sort of hashing for caching puposes. Not even sure it works at all in SSR, even if in a prerendered route. I might try.

RodrigoTomeES commented 1 week ago

@delucis @alexanderniebuhr hi! There are very pretty news, Cloudflare add a lot of compatibilities in workes with Node.js maybe now it would be easy to add support!

https://blog.cloudflare.com/builder-day-2024-announcements/