File size: 2,834 Bytes
814c07e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import { defineConfig } from 'vite';
import { resolve } from 'node:path';
import { existsSync, mkdirSync, cpSync, readFileSync } from 'node:fs';

// Copy onnxruntime-web's .wasm files into public/ at config-load time so Vite serves them.
const ortDist = resolve(__dirname, 'node_modules/onnxruntime-web/dist');
const publicOrt = resolve(__dirname, 'public/ort');
if (existsSync(ortDist) && !existsSync(publicOrt)) {
  mkdirSync(publicOrt, { recursive: true });
  cpSync(ortDist, publicOrt, { recursive: true });
}

// In vitest (VITEST env var is set), keep the real `fs` so Node tests can
// use fs.readFileSync for the temp-file approach.  In the Vite browser build
// alias both `fs` and `node:fs` to our thin browser shim.
const isTest = Boolean(process.env.VITEST);

export default defineConfig({
  server: {
    port: 5173,
    headers: {
      // Required for SharedArrayBuffer / multi-threaded WASM (COOP+COEP).
      // With numThreads=1 these aren't strictly needed, but harmless to set.
      'Cross-Origin-Opener-Policy': 'same-origin',
      'Cross-Origin-Embedder-Policy': 'require-corp',
    },
  },
  plugins: [
    {
      // Intercept /ort/*.mjs requests and serve them as plain ESM before
      // Vite's transform middleware can block them (Vite 8 refuses to serve
      // JS/CSS from /public via the module pipeline, but onnxruntime-web
      // needs to dynamically import its threading shim from that path).
      name: 'ort-mjs-passthrough',
      enforce: 'pre',
      configureServer(server) {
        // Use unshift to insert BEFORE Vite's own middleware stack.
        server.middlewares.stack.unshift({
          route: '',
          handle: (req: any, res: any, next: any) => {
            const url: string = req.url ?? '';
            if (url.startsWith('/ort/') && (url.includes('.mjs') || url.includes('.wasm'))) {
              const clean = url.split('?')[0];
              const filePath = resolve(__dirname, 'public' + clean);
              if (existsSync(filePath)) {
                const content = readFileSync(filePath);
                const mime = clean.endsWith('.mjs')
                  ? 'application/javascript; charset=utf-8'
                  : 'application/wasm';
                res.setHeader('Content-Type', mime);
                res.setHeader('Cache-Control', 'no-cache');
                res.end(content);
                return;
              }
            }
            next();
          },
        });
      },
    },
  ],
  test: { environment: 'node' },
  resolve: isTest
    ? {}
    : {
        alias: {
          // sentencepiece-js uses: var fs = require('fs')
          // Vite will resolve this alias for the browser bundle.
          fs: resolve(__dirname, 'src/sp-fs-shim.ts'),
          'node:fs': resolve(__dirname, 'src/sp-fs-shim.ts'),
        },
      },
});