withastro / adapters

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

"Shared" wasm module no longer builds #250

Closed adrianlyjak closed 2 months ago

adrianlyjak commented 2 months ago

Astro Info

Astro                    v4.5.8
Node                     v21.7.3
System                   macOS (arm64)
Package Manager          npm
Output                   hybrid
Adapter                  @astrojs/cloudflare
Integrations             none

Describe the Bug

After upgrading to astro v10 (from v8), my wasm module imports stopped working. After investigating the tests, I discovered that the differences seems to be that in my build, a shared file that imports a wasm module is used both within an SSR route and a SSG route. When this scenario occurs, the astro build ends in an obscure error:

file:///Users/adrianlyjak/dev/withastro-adapters/packages/cloudflare/test/fixtures/wasm/dist/_worker.js/chunks/hybrid_DqxhzLZ0.mjs?time=1714010209741
Unknown file extension ".wasm" for /Users/adrianlyjak/dev/withastro-adapters/packages/cloudflare/test/fixtures/wasm/dist/_worker.js/add.1ot1qwu.wasm
  Stack trace:
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
    at defaultLoad (node:internal/modules/esm/load:143:22)
    at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:285:45)

This change modifies the tests to reproduce the error

It seems like there's a flaw in the logic of splitting up a wasm import between pre-rendered and server rendered mode, it could be both!

            const isPrerendered = Object.keys(chunk.modules).some(
                (moduleId) => this.getModuleInfo(moduleId)?.meta?.astro?.pageOptions?.prerender === true
            );

            let final = code;

            // SSR
            if (!isPrerendered) {
                // replace with .wasm for workerd environments
            }

            // SSG
            if (isPrerendered) {
                // replace with .wasm.mjs for nodelike environments
            }

I'm thinking that this needs to be approached some other way. The best I can think of is to build the code for node while still emitting bundled assets, and then do a last minute minor modification to update the imports to point to the asset for cloudflare workers

What's the expected result?

You should be able to import shared wasm modules like before

Link to Minimal Reproducible Example

https://github.com/withastro/adapters/compare/main...adrianlyjak:withastro-adapters:shared-wasm

Participation

alexanderniebuhr commented 2 months ago

@adrianlyjak Thank you for the well detailed issue report, I think the option to have a shared wasm file was just overlooked.