mirror of
https://github.com/pesde-pkg/pesde.git
synced 2024-12-13 03:40:37 +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 remarkGithubAdmonitionsToDirectives from "remark-github-admonitions-to-directives"
|
||||||
import remarkParse from "remark-parse"
|
import remarkParse from "remark-parse"
|
||||||
import remarkRehype from "remark-rehype"
|
import remarkRehype from "remark-rehype"
|
||||||
import { createCssVariablesTheme, createHighlighter } from "shiki"
|
import { createCssVariablesTheme, createHighlighter, loadWasm } from "shiki"
|
||||||
import { unified } from "unified"
|
import { unified } from "unified"
|
||||||
import type { Node } from "unist"
|
import type { Node } from "unist"
|
||||||
import { map } from "unist-util-map"
|
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: [],
|
themes: [],
|
||||||
langs: [],
|
langs: [],
|
||||||
})
|
})
|
||||||
|
})()
|
||||||
|
|
||||||
const ADMONITION_TYPES = {
|
const ADMONITION_TYPES = {
|
||||||
note: {
|
note: {
|
||||||
|
|
|
@ -1,6 +1,89 @@
|
||||||
import { sveltekit } from "@sveltejs/kit/vite"
|
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({
|
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