astro-og-canvas icon indicating copy to clipboard operation
astro-og-canvas copied to clipboard

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

Open RodrigoTomeES opened this issue 1 year ago • 14 comments

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:

  • ~~deterministic-object-hash #1 PR~~
  • canvaskit-wasm: this package should be compatible with browser https://www.npmjs.com/package/canvaskit-wasm#browser maybe changing some part of the code of this library

RodrigoTomeES avatar Nov 17 '23 16:11 RodrigoTomeES

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

RodrigoTomeES avatar Nov 17 '23 23:11 RodrigoTomeES

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)

RodrigoTomeES avatar Nov 21 '23 18:11 RodrigoTomeES

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!

delucis avatar Nov 21 '23 23:11 delucis

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 🤔

RodrigoTomeES avatar Nov 22 '23 07:11 RodrigoTomeES

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

alexanderniebuhr avatar Nov 22 '23 19:11 alexanderniebuhr

@alexanderniebuhr could you take a look at the problem?

RodrigoTomeES avatar Dec 10 '23 18:12 RodrigoTomeES

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

alexanderniebuhr avatar Dec 11 '23 18:12 alexanderniebuhr

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

RodrigoTomeES avatar Feb 19 '24 11:02 RodrigoTomeES

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

alexanderniebuhr avatar Feb 20 '24 06:02 alexanderniebuhr

@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?

delucis avatar Feb 20 '24 08:02 delucis

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

alexanderniebuhr avatar Feb 20 '24 09:02 alexanderniebuhr

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.

delucis avatar Feb 20 '24 09:02 delucis

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 :)

alexanderniebuhr avatar Feb 20 '24 09:02 alexanderniebuhr

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.

itsmatteomanf avatar May 18 '24 09:05 itsmatteomanf