Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(worker): using data URLs for inline shared worker #12014

Merged
merged 10 commits into from
Mar 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat(worker): support inlineUrl of worker config
  • Loading branch information
fi3ework committed Mar 17, 2023
commit e03cc1a55572459b474fd21af91dbd5e6cbc29ec
9 changes: 8 additions & 1 deletion docs/config/worker-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ Options related to Web Workers.
## worker.format

- **Type:** `'es' | 'iife'`
- **Default:** `iife`
- **Default:** `'iife'`

Output format for worker bundle.

## worker.inlineUrl

- **Type:** `'blob' | 'data'`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It better to rename by base64?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good naming, updated.

- **Default:** `'blob'`

URL type for inline worker, when setting to `'blob'`, the worker will be loaded as a blob URL with a fallback to data URL. Set to `'data'` to load the worker as a data URL.

## worker.plugins

- **Type:** [`(Plugin | Plugin[])[]`](./shared-options#plugins)
Expand Down
7 changes: 7 additions & 0 deletions packages/vite/src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ export interface UserConfig {
* @default 'iife'
*/
format?: 'es' | 'iife'
/**
* URL type for inline worker
* @default 'blob'
*/
inlineUrl?: 'blob' | 'data'
/**
* Vite plugins that apply to worker bundle
*/
Expand Down Expand Up @@ -315,6 +320,7 @@ export interface LegacyOptions {

export interface ResolveWorkerOptions extends PluginHookUtils {
format: 'es' | 'iife'
inlineUrl: 'blob' | 'data'
plugins: Plugin[]
rollupOptions: RollupOptions
}
Expand Down Expand Up @@ -633,6 +639,7 @@ export async function resolveConfig(
workerConfig = await runConfigHook(workerConfig, workerUserPlugins, configEnv)
const resolvedWorkerOptions: ResolveWorkerOptions = {
format: workerConfig.worker?.format || 'iife',
inlineUrl: workerConfig.worker?.inlineUrl || 'blob',
plugins: [],
rollupOptions: workerConfig.worker?.rollupOptions || {},
getSortedPlugins: undefined!,
Expand Down
6 changes: 4 additions & 2 deletions packages/vite/src/node/plugins/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {

// stringified url or `new URL(...)`
let url: string
const { format } = config.worker
const { format, inlineUrl } = config.worker
const workerConstructor =
query.sharedworker != null ? 'SharedWorker' : 'Worker'
const workerType = isBuild
Expand All @@ -300,7 +300,9 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
export default function WorkerWrapper() {
const objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if setting base64 is not need to createObjectURL

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated. Separate the blob and base64 code to make it more readable for human.

try {
return objURL ? new ${workerConstructor}(objURL) : new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions});
return objURL && ${
inlineUrl === 'blob'
} ? new ${workerConstructor}(objURL) : new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions});
} finally {
objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL);
}
Expand Down
3 changes: 3 additions & 0 deletions playground/worker/__tests__/es/es-worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ describe.runIf(isBuild)('build', () => {
// inlined
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`)
expect(content).toMatch(`window.Blob`)
expect(content).toMatch(
/try\{return e\?new Worker\(.+\):new Worker\("data:application\/javascript;base64,"\+/,
)
})

test('worker emitted and import.meta.url in nested worker (build)', async () => {
Expand Down
19 changes: 19 additions & 0 deletions playground/worker/__tests__/inline-url/inline-url-worker.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import fs from 'node:fs'
import path from 'node:path'
import { describe, expect, test } from 'vitest'
import { isBuild, testDir } from '~utils'

describe.runIf(isBuild)('build', () => {
// assert correct files
test('inlined code generation', async () => {
const assetsDir = path.resolve(testDir, 'dist/inline-url/assets')
const files = fs.readdirSync(assetsDir)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')

// inlined
expect(content).toMatch(
`;try{return new Worker("data:application/javascript;base64,"+`,
)
})
})
1 change: 1 addition & 0 deletions playground/worker/__tests__/inline-url/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../vite.config-inline-url')
3 changes: 3 additions & 0 deletions playground/worker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"dev:relative-base": "WORKER_MODE=inline vite --config ./vite.config-relative-base.js dev",
"build:relative-base": "WORKER_MODE=inline vite --config ./vite.config-relative-base.js build",
"preview:relative-base": "WORKER_MODE=inline vite --config ./vite.config-relative-base.js preview",
"dev:inline-url": "vite --config ./vite.config-inline-url.js dev",
"build:inline-url": "vite --config ./vite.config-inline-url.js build",
"preview:inline-url": "vite --config ./vite.config-inline-url.js preview",
"debug": "node --inspect-brk ../../packages/vite/bin/vite"
},
"dependencies": {
Expand Down
5 changes: 5 additions & 0 deletions playground/worker/vite.config-inline-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = require('./vite.config-es')
config.worker.inlineUrl = 'data'
config.base = '/inline-url/'
config.build.outDir = 'dist/inline-url'
module.exports = config