Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
19 changes: 16 additions & 3 deletions packages/playground/worker/__tests__/es/es-worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,20 @@ test.concurrent.each([[true], [false]])('shared worker', async (doTick) => {
await waitSharedWorkerTick(page)
})

test('worker emitted', async () => {
await untilUpdated(() => page.textContent('.nested-worker'), 'pong')
test('worker emitted and import.meta.url in nested worker', async () => {
expect(await page.textContent('.nested-worker')).toMatch('/worker-nested')
expect(await page.textContent('.nested-worker-module')).toMatch('/sub-worker')
expect(await page.textContent('.nested-worker-constructor')).toMatch(
'"type":"constructor"'
)
})

if (isBuild) {
const assetsDir = path.resolve(testDir, 'dist/es/assets')
// assert correct files
test('inlined code generation', async () => {
const files = fs.readdirSync(assetsDir)
expect(files.length).toBe(22)
expect(files.length).toBe(27)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const worker = files.find((f) => f.includes('my-worker'))
Expand Down Expand Up @@ -100,3 +104,12 @@ test('emit chunk', async () => {
'"A string/es/"'
)
})

test('import.meta.glob in worker', async () => {
expect(await page.textContent('.importMetaGlob-worker')).toMatch('["')
})

// FIXME after buildEsbuildPlugin renderChunk export default a() break token
// test('import.meta.globEager in worker', async () => {
// expect(await page.textContent('.importMetaGlobEager-worker')).toMatch('["')
// })
13 changes: 9 additions & 4 deletions packages/playground/worker/__tests__/iife/worker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ test.concurrent.each([[true], [false]])('shared worker', async (doTick) => {
})

test('worker emitted and import.meta.url in nested worker', async () => {
await untilUpdated(
() => page.textContent('.nested-worker'),
'pong http://localhost:3000/iife/sub-worker.js?worker_file'
expect(await page.textContent('.nested-worker')).toMatch('/worker-nested')
expect(await page.textContent('.nested-worker-module')).toMatch('/sub-worker')
expect(await page.textContent('.nested-worker-constructor')).toMatch(
'"type":"constructor"'
)
})

Expand All @@ -63,7 +64,7 @@ if (isBuild) {
// assert correct files
test('inlined code generation', async () => {
const files = fs.readdirSync(assetsDir)
expect(files.length).toBe(13)
expect(files.length).toBe(14)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const worker = files.find((f) => f.includes('my-worker'))
Expand Down Expand Up @@ -94,3 +95,7 @@ test('classic worker', async () => {
expect(await page.textContent('.classic-worker')).toMatch('A classic')
expect(await page.textContent('.classic-shared-worker')).toMatch('A classic')
})

test('import.meta.globEager in worker', async () => {
expect(await page.textContent('.importMetaGlobEager-worker')).toMatch('["')
})
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if (isBuild) {
test('sourcemap generation for web workers', async () => {
const files = fs.readdirSync(assetsDir)
// should have 2 worker chunk
expect(files.length).toBe(25)
expect(files.length).toBe(27)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const indexSourcemap = getSourceMapUrl(content)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if (isBuild) {
test('sourcemap generation for web workers', async () => {
const files = fs.readdirSync(assetsDir)
// should have 2 worker chunk
expect(files.length).toBe(13)
expect(files.length).toBe(14)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const indexSourcemap = getSourceMapUrl(content)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ if (isBuild) {
test('sourcemap generation for web workers', async () => {
const files = fs.readdirSync(assetsDir)
// should have 2 worker chunk
expect(files.length).toBe(25)
expect(files.length).toBe(27)
const index = files.find((f) => f.includes('main-module'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const indexSourcemap = getSourceMapUrl(content)
Expand Down
5 changes: 5 additions & 0 deletions packages/playground/worker/importMetaGlob.worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const modules = import.meta.glob('./modules/*js')

self.onmessage = function (e) {
self.postMessage(Object.keys(modules))
}
5 changes: 5 additions & 0 deletions packages/playground/worker/importMetaGlobEager.worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const modules = import.meta.globEager('./modules/*js')

self.onmessage = function (e) {
self.postMessage(Object.keys(modules))
}
29 changes: 28 additions & 1 deletion packages/playground/worker/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,25 @@ <h2 class="format-iife">format iife:</h2>
<code class="shared-worker-import-meta-url"></code>

<p>
import NestedWorker from './worker-nested-worker?worker' - nested worker
import NestedWorker from './worker-nested-worker?worker' - import.meta.url
<span class="classname">.nested-worker</span>
</p>
<code class="nested-worker"></code>

<p>
import NestedWorker from './worker-nested-worker?worker' - nested module
worker
<span class="classname">.nested-worker-module</span>
</p>
<code class="nested-worker-module"></code>

<p>
import NestedWorker from './worker-nested-worker?worker' - nested worker
constructor
<span class="classname">.nested-worker-constructor</span>
</p>
<code class="nested-worker-constructor"></code>

<p>
new Worker(new URL('./classic-worker.js', import.meta.url))
<span class="classname">.classic-worker</span>
Expand All @@ -58,9 +72,22 @@ <h2 class="format-iife">format iife:</h2>
</p>
<code class="classic-shared-worker"></code>

<p>
use import.meta.globEager in iife worker
<span class="classname">.importMetaGlobEager-worker</span>
</p>
<code class="importMetaGlobEager-worker"></code>

<hr />

<h2 class="format-es"></h2>

<p>
use import.meta.glob in es worker
<span class="classname">.importMetaGlob-worker</span>
</p>
<code class="importMetaGlob-worker"></code>

<p>
worker emit chunk <br />
module and worker:worker in worker file <br />
Expand Down
19 changes: 17 additions & 2 deletions packages/playground/worker/worker-nested-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ self.onmessage = (event) => {
}
}

subWorker.onmessage = (event) => {
self.postMessage(event.data)
self.postMessage(import.meta.url)

subWorker.onmessage = (ev) => {
self.postMessage({
type: 'module',
data: ev.data
})
}

const classicWorker = new Worker(new URL('./url-worker.js', import.meta.url), {
type: 'module'
})
classicWorker.addEventListener('message', (ev) => {
self.postMessage({
type: 'constructor',
data: ev.data
})
})
9 changes: 9 additions & 0 deletions packages/playground/worker/worker/main-format-es.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// run when format es
import NestedWorker from '../emit-chunk-nested-worker?worker'
import ImportMetaGlobWorker from '../importMetaGlob.worker?worker'

function text(el, text) {
document.querySelector(el).textContent = text
Expand Down Expand Up @@ -39,3 +40,11 @@ const moduleWorker = new Worker(
moduleWorker.addEventListener('message', (ev) => {
text('.module-and-worker-worker', JSON.stringify(ev.data))
})

const importMetaGlobWorker = new ImportMetaGlobWorker()

importMetaGlobWorker.postMessage('1')

importMetaGlobWorker.addEventListener('message', (e) => {
text('.importMetaGlob-worker', JSON.stringify(e.data))
})
13 changes: 13 additions & 0 deletions packages/playground/worker/worker/main-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import InlineWorker from '../my-worker?worker&inline'
import mySharedWorker from '../my-shared-worker?sharedworker&name=shared'
import TSOutputWorker from '../possible-ts-output-worker?worker'
import NestedWorker from '../worker-nested-worker?worker'
import ImportMetaGlobEagerWorker from '../importMetaGlobEager.worker?worker'
import { mode } from '../modules/workerImport'

function text(el, text) {
Expand Down Expand Up @@ -56,6 +57,10 @@ const nestedWorker = new NestedWorker()
nestedWorker.addEventListener('message', (ev) => {
if (typeof ev.data === 'string') {
text('.nested-worker', JSON.stringify(ev.data))
} else if (ev.data.type === 'module') {
text('.nested-worker-module', JSON.stringify(ev.data))
} else if (ev.data.type === 'constructor') {
text('.nested-worker-constructor', JSON.stringify(ev.data))
}
})
nestedWorker.postMessage('ping')
Expand Down Expand Up @@ -83,3 +88,11 @@ w2.port.addEventListener('message', (ev) => {
text('.shared-worker-import-meta-url', JSON.stringify(ev.data))
})
w2.port.start()

const importMetaGlobEagerWorker = new ImportMetaGlobEagerWorker()

importMetaGlobEagerWorker.postMessage('1')

importMetaGlobEagerWorker.addEventListener('message', (e) => {
text('.importMetaGlobEager-worker', JSON.stringify(e.data))
})
23 changes: 16 additions & 7 deletions packages/vite/src/node/plugins/importAnalysisBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ function preload(baseModule: () => Promise<{}>, deps?: string[]) {
*/
export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
const ssr = !!config.build.ssr
const insertPreload = !(ssr || !!config.build.lib)
const isWorker = config.isWorker
const insertPreload = !(ssr || !!config.build.lib || isWorker)

const scriptRel = config.build.polyfillModulePreload
? `'modulepreload'`
Expand Down Expand Up @@ -121,11 +121,6 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
return
}

if (isWorker) {
// preload method use `document` and can't run in the worker
return
}

await init

let imports: readonly ImportSpecifier[] = []
Expand Down Expand Up @@ -157,6 +152,18 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
source.slice(start, end) === 'import.meta' &&
source.slice(end, end + 5) === '.glob'
) {
// es worker allow globEager / glob
// iife worker just allow globEager
if (
isWorker &&
config.worker.format === 'iife' &&
source.slice(end, end + 10) !== '.globEager'
) {
this.error(
'can not use dynamic import(import.meta.glob) in iife worker. Just support import.meta.globEager in iife worker.',
end
)
}
const { importsString, exp, endIndex, isEager } =
await transformImportGlob(
source,
Expand All @@ -180,7 +187,9 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
if (dynamicIndex > -1 && insertPreload) {
needPreloadHelper = true
const original = source.slice(expStart, expEnd)
const replacement = `${preloadMethod}(() => ${original},${isModernFlag}?"${preloadMarker}":void 0)`
const replacement = isWorker
? `() => ${original}`
: `${preloadMethod}(() => ${original},${isModernFlag}?"${preloadMarker}":void 0)`
str().overwrite(expStart, expEnd, replacement, { contentOnly: true })
}

Expand Down
3 changes: 2 additions & 1 deletion packages/vite/src/node/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { clientInjectionsPlugin } from './clientInjections'
import { buildHtmlPlugin, htmlInlineProxyPlugin } from './html'
import { wasmPlugin } from './wasm'
import { modulePreloadPolyfillPlugin } from './modulePreloadPolyfill'
import { webWorkerPlugin } from './worker'
import { webWorkerPlugin, webWorkerImportMetaUrlPlugin } from './worker'
import { preAliasPlugin } from './preAlias'
import { definePlugin } from './define'
import { ssrRequireHookPlugin } from './ssrRequireHook'
Expand Down Expand Up @@ -72,6 +72,7 @@ export async function resolvePlugins(
isBuild && buildHtmlPlugin(config),
workerImportMetaUrlPlugin(config),
...buildPlugins.pre,
isBuild && webWorkerImportMetaUrlPlugin(config),
...postPlugins,
...buildPlugins.post,
// internal server-only plugins are always applied after everything else
Expand Down
22 changes: 17 additions & 5 deletions packages/vite/src/node/plugins/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ export async function workerFileToUrl(

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

return {
name: 'vite:worker',
Expand Down Expand Up @@ -276,11 +275,24 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {
}`,
map: { mappings: '' } // Empty sourcemap to supress Rolup warning
}
},
}
}
}

// just run in build mode
export function webWorkerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
const isWorker = config.isWorker

renderChunk(code) {
if (isWorker && code.includes('import.meta.url')) {
return code.replace('import.meta.url', 'self.location.href')
return {
name: 'vite:workerImportMetaUrl',
transform(code) {
if (isWorker && config.worker.format !== 'es') {
// if build with iife it will polyfill with rollup will be used document in the worker
// else if build with es it will replace with `define plugin` will got a unexpected data.
// so replace import.meta.url break the default handle.
// And it must be done at this (after `(?new Worker)new URL('xxx', import.meta.url)` match),
// Otherwise, the following regex will be incorrectly matched.
return code.replace(/\bimport.meta.url\b/g, 'self.location.href')
}
}
}
Expand Down