mirror of
https://github.com/pesde-pkg/pesde.git
synced 2024-12-12 11:00:36 +00:00
fix: wasm loading on cloudflare (#12)
This commit is contained in:
parent
af30701a21
commit
11a356c99a
2 changed files with 101 additions and 7 deletions
|
@ -18,15 +18,26 @@ import remarkGfm from "remark-gfm"
|
|||
import remarkGithubAdmonitionsToDirectives from "remark-github-admonitions-to-directives"
|
||||
import remarkParse from "remark-parse"
|
||||
import remarkRehype from "remark-rehype"
|
||||
import { createCssVariablesTheme, createHighlighter } from "shiki"
|
||||
import { createCssVariablesTheme, createHighlighter, loadWasm } from "shiki"
|
||||
import { unified } from "unified"
|
||||
import type { Node } from "unist"
|
||||
import { map } from "unist-util-map"
|
||||
|
||||
const highlighter = createHighlighter({
|
||||
// @ts-expect-error - typescript doesn't like the wasm import
|
||||
import onigWasm from "shiki/onig.wasm"
|
||||
|
||||
const loadOnigWasm = (async () => {
|
||||
await loadWasm(onigWasm())
|
||||
})()
|
||||
|
||||
const highlighter = (async () => {
|
||||
await loadOnigWasm
|
||||
|
||||
return await createHighlighter({
|
||||
themes: [],
|
||||
langs: [],
|
||||
})
|
||||
})
|
||||
})()
|
||||
|
||||
const ADMONITION_TYPES = {
|
||||
note: {
|
||||
|
|
|
@ -1,6 +1,89 @@
|
|||
import { sveltekit } from "@sveltejs/kit/vite"
|
||||
import { defineConfig } from "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()],
|
||||
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)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue