From 08ff86f2c4864b04f89e2eb8511a4ead39af32e8 Mon Sep 17 00:00:00 2001 From: alex8088 <244096523@qq.com> Date: Sun, 3 Mar 2024 19:08:48 +0800 Subject: [PATCH] feat: easy way to fork processes and use workers --- node.d.ts | 6 ++++ src/config.ts | 2 ++ src/plugins/modulePath.ts | 65 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/plugins/modulePath.ts diff --git a/node.d.ts b/node.d.ts index 09bcc6c..5b8b896 100644 --- a/node.d.ts +++ b/node.d.ts @@ -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 diff --git a/src/config.ts b/src/config.ts index c874bc9..8851240 100644 --- a/src/config.ts +++ b/src/config.ts @@ -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() ]) diff --git a/src/plugins/modulePath.ts b/src/plugins/modulePath.ts new file mode 100644 index 0000000..e8573fa --- /dev/null +++ b/src/plugins/modulePath.ts @@ -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 + } + } +}