forked from withastro/astro
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cloudflare): Add support for wasm module imports for withastro#8541
- Loading branch information
1 parent
d939878
commit 4d229e6
Showing
28 changed files
with
594 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@astrojs/cloudflare': minor | ||
--- | ||
|
||
Add support for loading wasm modules in the cloudflare adapter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
packages/integrations/cloudflare/src/wasm-module-loader.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import * as fs from 'node:fs'; | ||
import * as path from 'node:path'; | ||
import { type Plugin } from 'vite'; | ||
|
||
/** | ||
* Loads '*.wasm?module' imports as WebAssembly modules, which is the only way to load WASM in cloudflare workers. | ||
* Current proposal for WASM modules: https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration | ||
* Cloudflare worker WASM from javascript support: https://developers.cloudflare.com/workers/runtime-apis/webassembly/javascript/ | ||
* @returns Vite plugin to load WASM tagged with '?module' as a WASM modules | ||
*/ | ||
export function wasmModuleLoader(): Plugin { | ||
const postfix = '.wasm?module'; | ||
let isDev = false; | ||
|
||
return { | ||
name: 'vite:wasm-module-loader', | ||
enforce: 'pre', | ||
configResolved(config) { | ||
isDev = config.command === 'serve'; | ||
}, | ||
config(_, __) { | ||
// let vite know that file format and the magic import string is intentional, and will be handled in this plugin | ||
return { | ||
assetsInclude: ['**/*.wasm?module'], | ||
build: { rollupOptions: { external: /^__WASM_ASSET__.+\.wasm$/i } }, | ||
}; | ||
}, | ||
|
||
load(id, _) { | ||
if (!id.endsWith(postfix)) { | ||
return; | ||
} | ||
|
||
const filePath = id.slice(0, -1 * '?module'.length); | ||
if (isDev) { | ||
// when running in vite serve, do the file system reading dance | ||
return ` | ||
import fs from "node:fs" | ||
const wasmModule = new WebAssembly.Module(fs.readFileSync("${filePath}")); | ||
export default wasmModule; | ||
`; | ||
} else { | ||
// build to just a re-export of the original asset contents | ||
const assetId = this.emitFile({ | ||
type: 'asset', | ||
name: path.basename(filePath), | ||
source: fs.readFileSync(filePath), | ||
}); | ||
|
||
// import from magic asset string to be replaced later | ||
return ` | ||
import init from "__WASM_ASSET__${assetId}.wasm" | ||
export default init | ||
`; | ||
} | ||
}, | ||
|
||
// output original wasm file relative to the chunk | ||
renderChunk(code, chunk, _) { | ||
if (isDev) return; | ||
|
||
if (!/__WASM_ASSET__([a-z\d]+)\.wasm/g.test(code)) return; | ||
|
||
const final = code.replaceAll(/__WASM_ASSET__([a-z\d]+)\.wasm/g, (s, assetId) => { | ||
const fileName = this.getFileName(assetId); | ||
const relativePath = path.relative(path.dirname(chunk.fileName), fileName); | ||
return `./${relativePath}`; | ||
}); | ||
|
||
return { code: final }; | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
packages/integrations/cloudflare/test/fixtures/wasm-directory/astro.config.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import cloudflare from '@astrojs/cloudflare'; | ||
|
||
export default defineConfig({ | ||
adapter: cloudflare({ | ||
mode: 'directory' | ||
}), | ||
output: 'server' | ||
}); |
9 changes: 9 additions & 0 deletions
9
packages/integrations/cloudflare/test/fixtures/wasm-directory/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "@test/astro-cloudflare-wasm-function-per-route", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"@astrojs/cloudflare": "workspace:*", | ||
"astro": "workspace:*" | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
packages/integrations/cloudflare/test/fixtures/wasm-directory/src/pages/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { type APIContext, type EndpointOutput } from 'astro'; | ||
// @ts-ignore | ||
import mod from '../util/add.wasm?module'; | ||
|
||
const addModule: any = new WebAssembly.Instance(mod); | ||
|
||
|
||
export async function GET( | ||
context: APIContext | ||
): Promise<EndpointOutput | Response> { | ||
|
||
return new Response(JSON.stringify({ answer: addModule.exports.add(40, 2) }), { | ||
status: 200, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
} |
Binary file added
BIN
+41 Bytes
packages/integrations/cloudflare/test/fixtures/wasm-directory/src/util/add.wasm
Binary file not shown.
10 changes: 10 additions & 0 deletions
10
packages/integrations/cloudflare/test/fixtures/wasm-function-per-route/astro.config.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import cloudflare from '@astrojs/cloudflare'; | ||
|
||
export default defineConfig({ | ||
adapter: cloudflare({ | ||
mode: 'directory', | ||
functionPerRoute: true | ||
}), | ||
output: 'server' | ||
}); |
9 changes: 9 additions & 0 deletions
9
packages/integrations/cloudflare/test/fixtures/wasm-function-per-route/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "@test/astro-cloudflare-wasm-directory", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"@astrojs/cloudflare": "workspace:*", | ||
"astro": "workspace:*" | ||
} | ||
} |
Oops, something went wrong.