feat: easy way to fork processes and use workers

This commit is contained in:
alex8088 2024-03-03 19:08:48 +08:00
parent 0ce505a12f
commit 08ff86f2c4
3 changed files with 73 additions and 0 deletions

6
node.d.ts vendored
View file

@ -4,6 +4,12 @@ declare module '*?nodeWorker' {
export default function (options: WorkerOptions): Worker
}
// module path
declare module '*?modulePath' {
const src: string
export default src
}
// node asset
declare module '*?asset' {
const src: string

View file

@ -20,6 +20,7 @@ import assetPlugin from './plugins/asset'
import workerPlugin from './plugins/worker'
import importMetaUrlPlugin from './plugins/importMetaUrl'
import esmShimPlugin from './plugins/esm'
import modulePathPlugin from './plugins/modulePath'
import { isObject, isFilePathESM } from './utils'
export { defineConfig as defineViteConfig } from 'vite'
@ -137,6 +138,7 @@ export async function resolveConfig(
...electronMainVitePlugin({ root }),
assetPlugin(),
workerPlugin(),
modulePathPlugin(),
importMetaUrlPlugin(),
esmShimPlugin()
])

65
src/plugins/modulePath.ts Normal file
View file

@ -0,0 +1,65 @@
import type { Plugin } from 'vite'
import type { SourceMapInput } from 'rollup'
import MagicString from 'magic-string'
import { cleanUrl, parseRequest, toRelativePath } from '../utils'
const modulePathRE = /__VITE_MODULE_PATH__([\w$]+)__/g
/**
* Resolve `?modulePath` import and return the module bundle path.
*/
export default function modulePathPlugin(): Plugin {
let sourcemap: boolean | 'inline' | 'hidden' = false
return {
name: 'vite:module-path',
apply: 'build',
enforce: 'pre',
configResolved(config): void {
sourcemap = config.build.sourcemap
},
resolveId(id, importer): string | void {
const query = parseRequest(id)
if (query && typeof query.modulePath === 'string') {
return id + `&importer=${importer}`
}
},
load(id): string | void {
const query = parseRequest(id)
if (query && typeof query.modulePath === 'string' && typeof query.importer === 'string') {
const cleanPath = cleanUrl(id)
const hash = this.emitFile({
type: 'chunk',
id: cleanPath,
importer: query.importer
})
const refId = `__VITE_MODULE_PATH__${hash}__`
return `
import { join } from 'path'
export default join(__dirname, ${refId})`
}
},
renderChunk(code, chunk): { code: string; map: SourceMapInput } | null {
if (code.match(modulePathRE)) {
let match: RegExpExecArray | null
const s = new MagicString(code)
while ((match = modulePathRE.exec(code))) {
const [full, hash] = match
const filename = this.getFileName(hash)
const outputFilepath = toRelativePath(filename, chunk.fileName)
const replacement = JSON.stringify(outputFilepath)
s.overwrite(match.index, match.index + full.length, replacement, {
contentOnly: true
})
}
return {
code: s.toString(),
map: sourcemap ? s.generateMap({ hires: 'boundary' }) : null
}
}
return null
}
}
}