import { defineConfig, type Plugin } from 'vite'; import uni from '@dcloudio/vite-plugin-uni'; /** * sm-crypto-v2 两处 App 端适配: * 1) 内含 `await import("crypto")`(Node CSPRNG 兜底分支),会使 Rollup 产出第二个 chunk, * 与 App 端 app-service 的 iife 单文件格式冲突,构建期改写为同步引用。 * 2) 其顶层 `initRNGPool()` 在模块求值时执行,而 uni-app 虚拟入口会让 sm-crypto 先于 * src/signalr/polyfill.ts 执行(实测 bundle 中 sm-crypto 在 ~47k、polyfill 在 ~409k), * 导致初始化时 globalThis.crypto 尚不存在、随机数池永久为空(randomBytes 抛 * "random number pool is not ready")。给 randomBytes 加惰性重检,调用时再认一次 crypto。 */ function stripSmCryptoDynamicImport(): Plugin { return { name: 'strip-sm-crypto-dynamic-import', enforce: 'pre', transform(code, id) { if (!id.includes('sm-crypto-v2')) return null; let patched = code.replace( /const crypto = await import\(\s*\/\* webpackIgnore: true \*\/\s*"crypto"\s*\);/, 'const crypto = { webcrypto: globalThis.crypto };' ); patched = patched.replace( /function randomBytes\(length = 0\) \{\s*const array = new Uint8Array\(length\);\s*if \(_syncCrypto\) \{/, 'function randomBytes(length = 0) {\n const array = new Uint8Array(length);\n if (!_syncCrypto && "crypto" in globalThis) _syncCrypto = globalThis.crypto;\n if (_syncCrypto) {' ); return patched === code ? null : { code: patched, map: null }; }, }; } export default defineConfig({ plugins: [stripSmCryptoDynamicImport(), uni()], server: { host: '0.0.0.0', }, });