Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(worker): bundle worker emit asset file (#6599)
  • Loading branch information
poyoho committed Mar 8, 2022
1 parent 87ecce5 commit 0ade335
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 20 deletions.
4 changes: 4 additions & 0 deletions packages/playground/wasm/__tests__/wasm.spec.ts
Expand Up @@ -9,3 +9,7 @@ test('should work when output', async () => {
await page.click('.output-wasm .run')
await untilUpdated(() => page.textContent('.output-wasm .result'), '24')
})

test('should work when wasm in worker', async () => {
await untilUpdated(() => page.textContent('.worker-wasm .result'), '3')
})
Binary file added packages/playground/wasm/add.wasm
Binary file not shown.
15 changes: 15 additions & 0 deletions packages/playground/wasm/index.html
Expand Up @@ -12,9 +12,20 @@ <h3>When wasm is output, result should be 24</h3>
<span class="result"></span>
</div>

<div class="worker-wasm">
<h3>worker wasm</h3>
<span class="result"></span>
</div>

<script type="module">
import light from './light.wasm'
import heavy from './heavy.wasm'
import myWorker from './worker?worker'

const w = new myWorker()
w.addEventListener('message', (ev) => {
text('.worker-wasm .result', ev.data.result)
})

async function testWasm(init, resultElement) {
const { exported_func } = await init({
Expand All @@ -25,6 +36,10 @@ <h3>When wasm is output, result should be 24</h3>
exported_func()
}

function text(el, text) {
document.querySelector(el).textContent = text
}

document
.querySelector('.inline-wasm .run')
.addEventListener('click', async () =>
Expand Down
8 changes: 8 additions & 0 deletions packages/playground/wasm/vite.config.ts
@@ -0,0 +1,8 @@
import { defineConfig } from 'vite'
export default defineConfig({
build: {
// make can no emit light.wasm
// and emit add.wasm
assetsInlineLimit: 80
}
})
5 changes: 5 additions & 0 deletions packages/playground/wasm/worker.js
@@ -0,0 +1,5 @@
import init from './add.wasm'
init().then((exports) => {
// eslint-disable-next-line no-undef
self.postMessage({ result: exports.add(1, 2) })
})
22 changes: 9 additions & 13 deletions packages/playground/worker/__tests__/worker.spec.ts
Expand Up @@ -51,12 +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')
await untilUpdated(
() => page.textContent('.nested-worker-dynamic-import'),
'"msg":"pong"'
)
})

if (isBuild) {
const assetsDir = path.resolve(testDir, 'dist/assets')
// assert correct files
test('inlined code generation', async () => {
const files = fs.readdirSync(assetsDir)
expect(files.length).toBe(8)
expect(files.length).toBe(11)
const index = files.find((f) => f.includes('index'))
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8')
const worker = files.find((f) => f.includes('my-worker'))
Expand All @@ -75,18 +83,6 @@ if (isBuild) {
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`)
expect(content).toMatch(`window.Blob`)
})

test('worker need bundle', () => {
fs.readdirSync(assetsDir)
.filter(
(file) =>
file.includes('url-worker') || file.includes('url-shared-worker')
)
.forEach((file) => {
const content = fs.readFileSync(path.resolve(assetsDir, file), 'utf-8')
expect(content.startsWith('(function(){')).toBe(true)
})
})
}

test('classic worker is run', async () => {
Expand Down
15 changes: 15 additions & 0 deletions packages/playground/worker/index.html
Expand Up @@ -26,6 +26,9 @@
<p>new SharedWorker(new Url('path', import.meta.url), { type: 'module' })</p>
<div class="shared-worker-import-meta-url"></div>

<p>nested worker</p>
<div class="nested-worker"></div>
<div class="nested-worker-dynamic-import"></div>
<p>new Worker(new Url('path', import.meta.url))</p>
<div class="classic-worker"></div>

Expand All @@ -37,6 +40,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 { mode } from './workerImport'
import './classic-worker'

Expand Down Expand Up @@ -114,4 +118,15 @@
)
})
w2.port.start()

const nestedWorker = new NestedWorker()
nestedWorker.addEventListener('message', (ev) => {
console.log(ev)
if (typeof ev.data === 'string') {
text('.nested-worker', ev.data)
} else {
text('.nested-worker-dynamic-import', JSON.stringify(ev.data))
}
})
nestedWorker.postMessage('ping')
</script>
13 changes: 13 additions & 0 deletions packages/playground/worker/sub-worker.js
@@ -0,0 +1,13 @@
self.onmessage = (event) => {
if (event.data === 'ping') {
self.postMessage('pong')
}
}
const data = import('./workerImport')
data.then((data) => {
const { mode, msg } = data
self.postMessage({
mode,
msg
})
})
4 changes: 1 addition & 3 deletions packages/playground/worker/vite.config.ts
Expand Up @@ -2,10 +2,8 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
import { defineConfig } from 'vite'

export default defineConfig({
build: {
target: process.env.NODE_ENV === 'production' ? 'chrome60' : 'esnext'
},
worker: {
format: 'es',
plugins: [vueJsx()]
}
})
13 changes: 13 additions & 0 deletions packages/playground/worker/worker-nested-worker.js
@@ -0,0 +1,13 @@
import SubWorker from './sub-worker?worker'

const subWorker = new SubWorker()

self.onmessage = (event) => {
if (event.data === 'ping') {
subWorker.postMessage('ping')
}
}

subWorker.onmessage = (event) => {
self.postMessage(event.data)
}
21 changes: 18 additions & 3 deletions packages/vite/src/node/plugins/worker.ts
Expand Up @@ -10,6 +10,7 @@ import { onRollupWarning } from '../build'
const WorkerFileId = 'worker_file'

export async function bundleWorkerEntry(
ctx: Rollup.TransformPluginContext,
config: ResolvedConfig,
id: string
): Promise<Buffer> {
Expand All @@ -27,11 +28,25 @@ export async function bundleWorkerEntry(
})
let code: string
try {
const { output } = await bundle.generate({
const {
output: [outputCode, ...outputChunks]
} = await bundle.generate({
format,
sourcemap: config.build.sourcemap
})
code = output[0].code
code = outputCode.code
outputChunks.forEach((outputChunk) => {
if (outputChunk.type === 'asset') {
ctx.emitFile(outputChunk)
}
if (outputChunk.type === 'chunk') {
ctx.emitFile({
fileName: `${config.build.assetsDir}/${outputChunk.fileName}`,
source: outputChunk.code,
type: 'asset'
})
}
})
} finally {
await bundle.close()
}
Expand Down Expand Up @@ -72,7 +87,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin {

let url: string
if (isBuild) {
const code = await bundleWorkerEntry(config, id)
const code = await bundleWorkerEntry(this, config, id)
if (query.inline != null) {
const { format } = config.worker
const workerOptions = format === 'es' ? '{type: "module"}' : '{}'
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/plugins/workerImportMetaUrl.ts
Expand Up @@ -138,7 +138,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
const file = path.resolve(path.dirname(id), rawUrl.slice(1, -1))
let url: string
if (isBuild) {
const content = await bundleWorkerEntry(config, file)
const content = await bundleWorkerEntry(this, config, file)
const basename = path.parse(cleanUrl(file)).name
const contentHash = getAssetHash(content)
const fileName = path.posix.join(
Expand Down

0 comments on commit 0ade335

Please sign in to comment.