liding
21 小时以前 303d42574231d0cc57f18a736bf8047d158233ce
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
import { createRequire } from 'node:module'
import { readFileSync, readdirSync } from 'node:fs'
import path from 'node:path'
import { transformWithEsbuild } from 'vite'
import { installCryptoRandomUUID } from '../../src/utils/cryptoRandomUUID.js'
 
const moduleId = 'virtual:superdoc-http-worker-url'
const resolvedId = '\0' + moduleId
 
// 为 SuperDoc 官方 Worker 添加 HTTP 下的 UUID 兼容入口。
// emitFile 按最终内容生成 hash,发布后不会复用旧 Worker 的浏览器缓存。
export default function superdocHttpWorker() {
  let base
  let building
  let source
  const route = '__superdoc_http_worker.js'
  return {
    name: 'superdoc-http-worker',
    configResolved(config) {
      base = config.base
      building = config.command === 'build'
      const require = createRequire(import.meta.url)
      const assetDir = path.join(path.dirname(require.resolve('@superdoc/docx-engine/package.json')), 'dist/assets')
      const entries = readdirSync(assetDir).filter(name => /^dom-worker-entry-.*\.js$/.test(name))
      if (entries.length !== 1) throw new Error('无法确定 SuperDoc 文档 Worker,请检查依赖版本')
      source = `;(${installCryptoRandomUUID.toString()})();\n` + readFileSync(path.join(assetDir, entries[0]), 'utf8')
    },
    resolveId(id) {
      if (id === moduleId) return resolvedId
    },
    async load(id) {
      if (id !== resolvedId) return
      if (!building) return `export default ${JSON.stringify(base + route)}`
      const minified = await transformWithEsbuild(source, 'superdoc-http-worker.js', { minify: true, legalComments: 'inline' })
      const reference = this.emitFile({ type: 'asset', name: 'superdoc-http-worker.js', source: minified.code })
      return `export default import.meta.ROLLUP_FILE_URL_${reference}`
    },
    configureServer(server) {
      server.middlewares.use((req, res, next) => {
        if (req.url?.split('?')[0] !== base + route) return next()
        res.setHeader('Content-Type', 'text/javascript; charset=utf-8')
        res.setHeader('Cache-Control', 'no-cache')
        res.end(source)
      })
    }
  }
}