pesde/website/vite.config.ts
2024-11-30 22:22:14 +01:00

89 lines
2.7 KiB
TypeScript

import { sveltekit } from "@sveltejs/kit/vite"
import { readFile } from "node:fs/promises"
import path from "node:path"
import { defineConfig, type Plugin, type ResolvedConfig } from "vite"
export default defineConfig({
plugins: [sveltekit(), cloudflareWasmImport()],
})
// This plugin allows us to import WebAssembly modules and have them work in
// both the browser, Node.js, and Cloudflare Workers.
function cloudflareWasmImport(): Plugin {
const wasmPostfix = ".wasm"
const importMetaPrefix = "___WASM_IMPORT_PATH___"
let config: ResolvedConfig
return {
name: "cloudflare-wasm-import",
configResolved(resolvedConfig) {
config = resolvedConfig
},
async load(id) {
if (!id.endsWith(wasmPostfix)) return
if (config.command === "serve") {
// Running dev server
// We generate a module that on the browser will fetch the WASM file
// (through a Vite `?url` import), and on the server will read the file
// from the file system.
return `
import WASM_URL from ${JSON.stringify(`${id}?url`)}
let promise
export default function() {
if (import.meta.env.SSR) {
return promise ?? (promise = import("node:fs/promises")
.then(({ readFile }) => readFile(${JSON.stringify(id)})))
} else {
return promise ?? (promise = fetch(WASM_URL).then(r => r.arrayBuffer()))
}
}
`
}
// When building, we emit the WASM file as an asset and generate a module
// that will fetch the asset in the browser, import the WASM file when in
// a Cloudflare Worker, and read the file from the file system when in
// Node.js.
const wasmSource = await readFile(id)
const refId = this.emitFile({
type: "asset",
name: path.basename(id),
source: wasmSource,
})
return `
import WASM_URL from ${JSON.stringify(`${id}?url`)}
let promise
export default function() {
if (import.meta.env.SSR) {
if (typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers") {
return promise ?? (promise = import(import.meta.${importMetaPrefix}${refId}))
} else {
return promise ?? (promise = import(\`\${"node:fs/promises"}\`)
.then(({ readFile }) => readFile(new URL(import.meta.ROLLUP_FILE_URL_${refId}))))
}
} else {
return promise ?? (promise = fetch(WASM_URL).then(r => r.arrayBuffer()))
}
}
`
},
resolveImportMeta(property, { chunkId }) {
if (!property?.startsWith(importMetaPrefix)) return
const refId = property.slice(importMetaPrefix.length)
const fileName = this.getFileName(refId)
const relativePath = path.relative(path.dirname(chunkId), fileName)
return JSON.stringify(relativePath)
},
}
}