withastro / adapters

Home for Astro's core maintained adapters
47 stars 26 forks source link

Cloudflare v10 breaks cloudflare build / wrangler preview with `imageService: "compile"` and Astro's `<Image />` component #213

Open dallyh opened 3 months ago

dallyh commented 3 months ago

Astro Info

Astro                    v4.5.12
Node                     v20.12.0
System                   Windows (x64)
Package Manager          npm
Output                   hybrid
Adapter                  @astrojs/cloudflare
Integrations             @astrojs/react

Describe the Bug

When using v10 version of the adapter, hybrid output mode and <Image/> component on a prerendered path, with combination of imageService: "compile" in the configuration, wrangler preview fails. This was not the case with previous version, it looks like there are modules being bundled which should not be bundler.

Steps to reproduce

Attaching additional modules:
┌──────────────────────────────────────────┬──────┬───────────┐
│ Name                                     │ Type │ Size      │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/astro/assets-service_Dj66YdWb.mjs │ esm  │ 12.29 KiB │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/astro_DBzb2nRr.mjs                │ esm  │ 83.90 KiB │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/image-endpoint_RvDj3-CK.mjs       │ esm  │ 0.18 KiB  │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/index_B6euTALA.mjs                │ esm  │ 0.18 KiB  │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/pages/image-endpoint_nxDOIah1.mjs │ esm  │ 0.06 KiB  │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/pages/index_CPLiUgeG.mjs          │ esm  │ 0.20 KiB  │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/prerender_H0Lv92GL.mjs            │ esm  │ 0.09 KiB  │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/test_2VqMiBwm.mjs                 │ esm  │ 0.17 KiB  │
├──────────────────────────────────────────┼──────┼───────────┤
│ chunks/vnode-children_VTcTc4QR.mjs       │ esm  │ 2.94 KiB  │
├──────────────────────────────────────────┼──────┼───────────┤
│ manifest_BEhMcueP.mjs                    │ esm  │ 18.13 KiB │
├──────────────────────────────────────────┼──────┼───────────┤
│ renderers.mjs                            │ esm  │ 85.67 KiB │
├──────────────────────────────────────────┼──────┼───────────┤
│ _noop-middleware.mjs                     │ esm  │ 0.12 KiB  │
└──────────────────────────────────────────┴──────┴───────────┘
✨ Compiled Worker successfully
 ⛅️ wrangler 3.39.0
-------------------
[wrangler:inf] Ready on http://127.0.0.1:4321
X [ERROR] Could not resolve "child_process"

    node_modules/detect-libc/lib/detect-libc.js:6:29:
      6 │ const childProcess = require('child_process');
        ╵                              ~~~~~~~~~~~~~~~

  The package "child_process" wasn't found on the file system but is built into node.
  Add "node_compat = true" to your wrangler.toml file and make sure to prefix the module name with "node:" to enable Node.js compatibility.

X [ERROR] Could not resolve "fs"                                                                                                                                                                                                                                                            

    node_modules/detect-libc/lib/filesystem.js:6:19:                                                                                                                                                                                                                                        
      6 │ const fs = require('fs');
        ╵                    ~~~~

  The package "fs" wasn't found on the file system but is built into node.
  Add "node_compat = true" to your wrangler.toml file and make sure to prefix the module name with "node:" to enable Node.js compatibility.

X [ERROR] Could not resolve "util"                                                                                                                                                                                                                                                          

    node_modules/sharp/lib/constructor.js:6:21:                                                                                                                                                                                                                                             
      6 │ const util = require('util');
        ╵                      ~~~~~~

  The package "util" wasn't found on the file system but is built into node.
  Add "node_compat = true" to your wrangler.toml file and make sure to prefix the module name with "node:" to enable Node.js compatibility.

X [ERROR] Could not resolve "stream"                                                                                                                                                                                                                                                        

    node_modules/sharp/lib/constructor.js:7:23:                                                                                                                                                                                                                                             
      7 │ const stream = require('stream');
        ╵                        ~~~~~~~~

  The package "stream" wasn't found on the file system but is built into node.
  Add "node_compat = true" to your wrangler.toml file and make sure to prefix the module name with "node:" to enable Node.js compatibility.

... more errors

What's the expected result?

imageService: "compile" should not break the ouputted build for Cloudflare.

Link to Minimal Reproducible Example

https://github.com/dallyh/astro-cf-10-issues/tree/image-service-compile

Participation

alexanderniebuhr commented 3 months ago

I thought we fixed this, but it came back.. The solution is to port the esbuild plugin to vite. I get to that as soon as possible..

https://github.com/withastro/adapters/blob/cloudflare-v9/packages/cloudflare/src/utils/sharpBundlePatch.ts

alexanderniebuhr commented 3 months ago

Please try @astrojs/cloudflare@0.0.0-cf-deps-chunk-20240406183753

dallyh commented 3 months ago

The build now fails completely with this message:

00:21:46 [build] output: "hybrid"
00:21:46 [build] directory: C:\Users\honda\git\astro-cf-10-issues\dist\
00:21:46 [build] adapter: @astrojs/cloudflare
00:21:46 [build] Collecting build info...
00:21:46 [build] ✓ Completed in 345ms.
00:21:46 [build] Building hybrid entrypoints...
00:21:49 [vite] ✓ built in 3.17s
00:21:49 [build] ✓ Completed in 3.28s.

 building client (vite) 
00:21:50 [vite] ✓ 30 modules transformed.
00:21:51 [vite] dist/_astro/ReactCounter.BkBRHHLQ.js    1.20 kB │ gzip:  0.70 kB
00:21:51 [vite] dist/_astro/index.NEDEFKed.js           6.71 kB │ gzip:  2.67 kB
00:21:51 [vite] dist/_astro/client.DbokQZWz.js        135.49 kB │ gzip: 43.80 kB
00:21:51 [vite] ✓ built in 1.51s
Cannot access 'escape' before initialization
  Stack trace:
    at file:///C:/Users/honda/git/astro-cf-10-issues/dist/_worker.js/chunks/astro_BrXF0lrZ.mjs:413:20
    at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
    at async generatePages (file:///C:/Users/honda/git/astro-cf-10-issues/node_modules/astro/dist/core/build/generate.js:96:16)
    at async AstroBuilder.build (file:///C:/Users/honda/git/astro-cf-10-issues/node_modules/astro/dist/core/build/index.js:134:5)
    at async build (file:///C:/Users/honda/git/astro-cf-10-issues/node_modules/astro/dist/core/build/index.js:46:3)

I've updated the example repo branch.

dallyh commented 3 months ago

"Fixing" the build like in this comment also works here. The preview works fine.

dallyh commented 1 month ago

@alexanderniebuhr is this also considered to be an issue somewhere upstream?

I thought we fixed this, but it came back.. The solution is to port the esbuild plugin to vite. I get to that as soon as possible..

https://github.com/withastro/adapters/blob/cloudflare-v9/packages/cloudflare/src/utils/sharpBundlePatch.ts

It looked it this could be fixed by this.

Btw. I haven't yet tried any versions past v10, maybe it got also fixed in the meantime?

Thanks!

alexanderniebuhr commented 1 month ago

This is still on my list, it's still a workaround for an upstream limitation, but we'll need to use a workaround here.

skf-funzt commented 1 month ago

"Fixing" the build like in this comment also works here. The preview works fine.

Same issue, but solved it with this comment

TL;DR

Install the package version with the workaround

pnpm add @astrojs/cloudflare@0.0.0-cf-deps-chunk-20240407075425

This results in having the package.json contain:

{
  ...
  "dependencies": {
    "@astrojs/cloudflare": "0.0.0-cf-deps-chunk-20240407075425",
    ...
  },
  ...
}

And the astro.config.ts needs the chunking enabled for sharp:

...
export default defineConfig({
  ...
  adapter: cloudflare({
    imageService: "compile",
    ...
    experimental: {
        manualChunks: ["sharp"]
    }
  }),
  ...
});

Works with build and preview. :ok_hand:

alexanderniebuhr commented 2 weeks ago

I don't expect this to be fixed by v11, but might be worth to try again.

dallyh commented 2 weeks ago

I updated the reproduction. Now there are less errors. Something still tries to use detect-libc when the Image component is in use.

[wrangler:inf] Ready on http://127.0.0.1:4321
X [ERROR] Could not resolve "child_process"

    node_modules/detect-libc/lib/detect-libc.js:6:29:
      6 │ const childProcess = require('child_process');
        ╵                              ~~~~~~~~~~~~~~~

  The package "child_process" wasn't found on the file system but is built into node.
  Add "node_compat = true" to your wrangler.toml file and make sure to prefix the module name with "node:" to enable Node.js compatibility.

X [ERROR] Could not resolve "fs"                                                                                                                                                                                                                                             

    node_modules/detect-libc/lib/filesystem.js:6:19:                                                                                                                                                                                                                         
      6 │ const fs = require('fs');
        ╵                    ~~~~

  The package "fs" wasn't found on the file system but is built into node.
  Add "node_compat = true" to your wrangler.toml file and make sure to prefix the module name with "node:" to enable Node.js compatibility.

Also compile is now default in v11, does that mean that every user using this sort of setup will see this error, or it will be just this specific case? What specifically is this tied to? I also tried switching to output server and then marking the page as prerender=true (basically switch the logic), and the result is the same.

alexanderniebuhr commented 2 weeks ago

Very good question, I'm not sure if everyone sees this. I want to fix this issue next though.