11import { exactRegex } from '@rolldown/pluginutils'
22import type { Plugin } from '../plugin'
3+ import { fsPathFromId } from '../utils'
34import { fileToUrl } from './asset'
45
56const wasmHelperId = '\0vite/wasm-helper.js'
@@ -26,46 +27,45 @@ const wasmHelper = async (opts = {}, url: string) => {
2627 }
2728 result = await WebAssembly . instantiate ( bytes , opts )
2829 } else {
29- if (
30- typeof process !== 'undefined' &&
31- process . versions &&
32- process . versions . node
33- ) {
34- const fs = await import ( 'node:fs/promises' )
35- if ( url . startsWith ( '/@fs/' ) ) {
36- url = url . slice ( 5 )
37- if ( ! / ^ [ A - Z ] : / i. test ( url ) ) {
38- url = `/${ url } `
39- }
40- } else if ( url . startsWith ( '/' ) ) {
41- url = url . slice ( 1 )
42- }
43- const buffer = await fs . readFile ( url )
44- result = await WebAssembly . instantiate ( buffer , opts )
45- } else {
46- // https://github.com/mdn/webassembly-examples/issues/5
47- // WebAssembly.instantiateStreaming requires the server to provide the
48- // correct MIME type for .wasm files, which unfortunately doesn't work for
49- // a lot of static file servers, so we just work around it by getting the
50- // raw buffer.
51- const response = await fetch ( url )
52- const contentType = response . headers . get ( 'Content-Type' ) || ''
53- if (
54- 'instantiateStreaming' in WebAssembly &&
55- contentType . startsWith ( 'application/wasm' )
56- ) {
57- result = await WebAssembly . instantiateStreaming ( response , opts )
58- } else {
59- const buffer = await response . arrayBuffer ( )
60- result = await WebAssembly . instantiate ( buffer , opts )
61- }
62- }
30+ result = await instantiateFromUrl ( url , opts )
6331 }
6432 return result . instance
6533}
6634
6735const wasmHelperCode = wasmHelper . toString ( )
6836
37+ const instantiateFromUrl = async ( url : string , opts ?: WebAssembly . Imports ) => {
38+ // https://github.com/mdn/webassembly-examples/issues/5
39+ // WebAssembly.instantiateStreaming requires the server to provide the
40+ // correct MIME type for .wasm files, which unfortunately doesn't work for
41+ // a lot of static file servers, so we just work around it by getting the
42+ // raw buffer.
43+ const response = await fetch ( url )
44+ const contentType = response . headers . get ( 'Content-Type' ) || ''
45+ if (
46+ 'instantiateStreaming' in WebAssembly &&
47+ contentType . startsWith ( 'application/wasm' )
48+ ) {
49+ return WebAssembly . instantiateStreaming ( response , opts )
50+ } else {
51+ const buffer = await response . arrayBuffer ( )
52+ return WebAssembly . instantiate ( buffer , opts )
53+ }
54+ }
55+
56+ const instantiateFromUrlCode = instantiateFromUrl . toString ( )
57+
58+ const instantiateFromFile = async (
59+ fsPath : string ,
60+ opts ?: WebAssembly . Imports ,
61+ ) => {
62+ const fs = await import ( 'node:fs/promises' )
63+ const buffer = await fs . readFile ( fsPath )
64+ return WebAssembly . instantiate ( buffer , opts )
65+ }
66+
67+ const instantiateFromFileCode = instantiateFromFile . toString ( )
68+
6969export const wasmHelperPlugin = ( ) : Plugin => {
7070 return {
7171 name : 'vite:wasm-helper' ,
@@ -80,11 +80,20 @@ export const wasmHelperPlugin = (): Plugin => {
8080 load : {
8181 filter : { id : [ exactRegex ( wasmHelperId ) , wasmInitRE ] } ,
8282 async handler ( id ) {
83+ const isServer = this . environment . config . consumer === 'server'
84+
8385 if ( id === wasmHelperId ) {
84- return `export default ${ wasmHelperCode } `
86+ const instantiateFromUrl = isServer
87+ ? instantiateFromFileCode
88+ : instantiateFromUrlCode
89+ return `
90+ const instantiateFromUrl = ${ instantiateFromUrl }
91+ export default ${ wasmHelperCode }
92+ `
8593 }
8694
87- const url = ( await fileToUrl ( this , id ) ) . split ( '?' ) [ 0 ]
95+ id = id . split ( '?' ) [ 0 ]
96+ const url = isServer ? fsPathFromId ( id ) : await fileToUrl ( this , id )
8897
8998 return `
9099 import initWasm from "${ wasmHelperId } "
0 commit comments