Skip to content

Commit

Permalink
feat(plugins/worker): Support shared inline worker
Browse files Browse the repository at this point in the history
  • Loading branch information
NotWoods authored Jul 6, 2021
1 parent 34a8137 commit ab008a3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
2 changes: 1 addition & 1 deletion packages/playground/worker/__tests__/worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ if (isBuild) {
expect(content).toMatch(`new Worker("/assets`)
expect(content).toMatch(`new SharedWorker("/assets`)
// inlined
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`)
expect(content).toMatch(`.createObjectURL(`)
})
}
61 changes: 45 additions & 16 deletions packages/vite/src/node/plugins/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,41 @@ function parseWorkerRequest(id: string): ParsedUrlQuery | null {

const WorkerFileId = 'worker_file'

/**
* Create a factory for the worker constructor string.
* Can be combined with other strings to build an inline script.
*
* @param query Parsed worker request data
* @returns Factory function taking URL and worker options.
* Null is returned if the worker request is invalid.
*/
function buildWorkerConstructor(query: ParsedUrlQuery | null) {
if (!query) {
return null
}

let workerConstructor: string
if (query.sharedworker != null) {
workerConstructor = 'SharedWorker'
} else if (query.worker != null) {
workerConstructor = 'Worker'
} else {
return null
}

return (urlVariable: string, options?: object) => {
if (options) {
return `new ${workerConstructor}(${urlVariable}, ${JSON.stringify(
options,
null,
2
)})`
} else {
return `new ${workerConstructor}(${urlVariable})`
}
}
}

export function webWorkerPlugin(config: ResolvedConfig): Plugin {
const isBuild = config.command === 'build'

Expand All @@ -28,10 +63,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
load(id) {
if (isBuild) {
const parsedQuery = parseWorkerRequest(id)
if (
parsedQuery &&
(parsedQuery.worker ?? parsedQuery.sharedworker) != null
) {
if (buildWorkerConstructor(parsedQuery) != null) {
return ''
}
}
Expand All @@ -44,10 +76,9 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
code: `import '${ENV_PUBLIC_PATH}'\n` + _
}
}
if (
query == null ||
(query && (query.worker ?? query.sharedworker) == null)
) {

const workerConstructor = buildWorkerConstructor(query)
if (query == null || workerConstructor == null) {
return
}

Expand Down Expand Up @@ -75,12 +106,13 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
return `const blob = new Blob([atob(\"${content.toString(
'base64'
)}\")], { type: 'text/javascript;charset=utf-8' });
const URL = window.URL || window.webkitURL;
export default function WorkerWrapper() {
const objURL = (window.URL || window.webkitURL).createObjectURL(blob);
const objURL = URL.createObjectURL(blob);
try {
return new Worker(objURL);
return ${workerConstructor('objUrl')};
} finally {
(window.URL || window.webkitURL).revokeObjectURL(objURL);
URL.revokeObjectURL(objURL);
}
}`
} else {
Expand All @@ -101,14 +133,11 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
url = injectQuery(url, WorkerFileId)
}

const workerConstructor =
query.sharedworker != null ? 'SharedWorker' : 'Worker'
const workerUrl = JSON.stringify(url)
const workerOptions = { type: 'module' }

return `export default function WorkerWrapper() {
return new ${workerConstructor}(${JSON.stringify(
url
)}, ${JSON.stringify(workerOptions, null, 2)})
return ${workerConstructor(workerUrl, workerOptions)};
}`
}
}
Expand Down

0 comments on commit ab008a3

Please sign in to comment.