-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(worker): Add sourcemap support for worker bundles (#5417)
- Loading branch information
1 parent
cb388e2
commit 465b6b9
Showing
10 changed files
with
481 additions
and
17 deletions.
There are no files selected for viewing
129 changes: 129 additions & 0 deletions
129
packages/playground/worker/__tests__/sourcemap-hidden/sourcemap-hidden-worker.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import fs from 'fs' | ||
import path from 'path' | ||
import { untilUpdated, isBuild, testDir } from '../../../testUtils' | ||
import { Page } from 'playwright-chromium' | ||
|
||
if (isBuild) { | ||
const assetsDir = path.resolve(testDir, 'dist/iife-sourcemap-hidden/assets') | ||
// assert correct files | ||
test('sourcemap generation for web workers', async () => { | ||
const files = fs.readdirSync(assetsDir) | ||
// should have 2 worker chunk | ||
expect(files.length).toBe(25) | ||
const index = files.find((f) => f.includes('main-module')) | ||
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8') | ||
const indexSourcemap = getSourceMapUrl(content) | ||
const worker = files.find((f) => /^my-worker\.\w+\.js$/.test(f)) | ||
const workerContent = fs.readFileSync( | ||
path.resolve(assetsDir, worker), | ||
'utf-8' | ||
) | ||
const workerSourcemap = getSourceMapUrl(workerContent) | ||
const sharedWorker = files.find((f) => | ||
/^my-shared-worker\.\w+\.js$/.test(f) | ||
) | ||
const sharedWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, sharedWorker), | ||
'utf-8' | ||
) | ||
const sharedWorkerSourcemap = getSourceMapUrl(sharedWorkerContent) | ||
const possibleTsOutputWorker = files.find((f) => | ||
/^possible-ts-output-worker\.\w+\.js$/.test(f) | ||
) | ||
const possibleTsOutputWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, possibleTsOutputWorker), | ||
'utf-8' | ||
) | ||
const possibleTsOutputWorkerSourcemap = getSourceMapUrl( | ||
possibleTsOutputWorkerContent | ||
) | ||
const workerNestedWorker = files.find((f) => | ||
/^worker-nested-worker\.\w+\.js$/.test(f) | ||
) | ||
const workerNestedWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, workerNestedWorker), | ||
'utf-8' | ||
) | ||
const workerNestedWorkerSourcemap = getSourceMapUrl( | ||
workerNestedWorkerContent | ||
) | ||
const subWorker = files.find((f) => /^sub-worker\.\w+\.js$/.test(f)) | ||
const subWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, subWorker), | ||
'utf-8' | ||
) | ||
const subWorkerSourcemap = getSourceMapUrl(subWorkerContent) | ||
|
||
expect(files).toContainEqual(expect.stringMatching(/^index\.\w+\.js\.map$/)) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^my-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^my-shared-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^possible-ts-output-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^worker-nested-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^sub-worker\.\w+\.js\.map$/) | ||
) | ||
|
||
// sourcemap should exist and have a data URL | ||
expect(indexSourcemap).toBe(null) | ||
expect(workerSourcemap).toBe(null) | ||
expect(sharedWorkerSourcemap).toBe(null) | ||
expect(possibleTsOutputWorkerSourcemap).toBe(null) | ||
expect(workerNestedWorkerSourcemap).toBe(null) | ||
expect(subWorkerSourcemap).toBe(null) | ||
|
||
// worker should have all imports resolved and no exports | ||
expect(workerContent).not.toMatch(`import`) | ||
expect(workerContent).not.toMatch(`export`) | ||
|
||
// shared worker should have all imports resolved and no exports | ||
expect(sharedWorkerContent).not.toMatch(`import`) | ||
expect(sharedWorkerContent).not.toMatch(`export`) | ||
|
||
// chunk | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap-hidden/assets/my-worker` | ||
) | ||
expect(content).toMatch(`new Worker("data:application/javascript;base64`) | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap-hidden/assets/possible-ts-output-worker` | ||
) | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap-hidden/assets/worker-nested-worker` | ||
) | ||
expect(content).toMatch( | ||
`new SharedWorker("/iife-sourcemap-hidden/assets/my-shared-worker` | ||
) | ||
|
||
// inlined | ||
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`) | ||
expect(content).toMatch(`window.Blob`) | ||
|
||
expect(workerNestedWorkerContent).toMatch( | ||
`new Worker("/iife-sourcemap-hidden/assets/sub-worker` | ||
) | ||
}) | ||
} else { | ||
// Workaround so that testing serve does not emit | ||
// "Your test suite must contain at least one test" | ||
test('true', () => { | ||
expect(true).toBe(true) | ||
}) | ||
} | ||
|
||
function getSourceMapUrl(code: string): string { | ||
const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g | ||
const results = regex.exec(code) | ||
|
||
if (results && results.length >= 2) { | ||
return results[1] | ||
} | ||
return null | ||
} |
1 change: 1 addition & 0 deletions
1
packages/playground/worker/__tests__/sourcemap-hidden/vite.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('../../vite.config-sourcemap')('hidden') |
112 changes: 112 additions & 0 deletions
112
packages/playground/worker/__tests__/sourcemap-inline/sourcemap-inline-worker.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import fs from 'fs' | ||
import path from 'path' | ||
import { untilUpdated, isBuild, testDir } from '../../../testUtils' | ||
import { Page } from 'playwright-chromium' | ||
|
||
if (isBuild) { | ||
const assetsDir = path.resolve(testDir, 'dist/iife-sourcemap-inline/assets') | ||
// assert correct files | ||
test('sourcemap generation for web workers', async () => { | ||
const files = fs.readdirSync(assetsDir) | ||
// should have 2 worker chunk | ||
expect(files.length).toBe(13) | ||
const index = files.find((f) => f.includes('main-module')) | ||
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8') | ||
const indexSourcemap = getSourceMapUrl(content) | ||
const worker = files.find((f) => /^my-worker\.\w+\.js$/.test(f)) | ||
const workerContent = fs.readFileSync( | ||
path.resolve(assetsDir, worker), | ||
'utf-8' | ||
) | ||
const workerSourcemap = getSourceMapUrl(workerContent) | ||
const sharedWorker = files.find((f) => | ||
/^my-shared-worker\.\w+\.js$/.test(f) | ||
) | ||
const sharedWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, sharedWorker), | ||
'utf-8' | ||
) | ||
const sharedWorkerSourcemap = getSourceMapUrl(sharedWorkerContent) | ||
const possibleTsOutputWorker = files.find((f) => | ||
/^possible-ts-output-worker\.\w+\.js$/.test(f) | ||
) | ||
const possibleTsOutputWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, possibleTsOutputWorker), | ||
'utf-8' | ||
) | ||
const possibleTsOutputWorkerSourcemap = getSourceMapUrl( | ||
possibleTsOutputWorkerContent | ||
) | ||
const workerNestedWorker = files.find((f) => | ||
/^worker-nested-worker\.\w+\.js$/.test(f) | ||
) | ||
const workerNestedWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, workerNestedWorker), | ||
'utf-8' | ||
) | ||
const workerNestedWorkerSourcemap = getSourceMapUrl( | ||
workerNestedWorkerContent | ||
) | ||
const subWorker = files.find((f) => /^sub-worker\.\w+\.js$/.test(f)) | ||
const subWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, subWorker), | ||
'utf-8' | ||
) | ||
const subWorkerSourcemap = getSourceMapUrl(subWorkerContent) | ||
|
||
// sourcemap should exist and have a data URL | ||
expect(indexSourcemap).toMatch(/^data:/) | ||
expect(workerSourcemap).toMatch(/^data:/) | ||
expect(sharedWorkerSourcemap).toMatch(/^data:/) | ||
expect(possibleTsOutputWorkerSourcemap).toMatch(/^data:/) | ||
expect(workerNestedWorkerSourcemap).toMatch(/^data:/) | ||
expect(subWorkerSourcemap).toMatch(/^data:/) | ||
|
||
// worker should have all imports resolved and no exports | ||
expect(workerContent).not.toMatch(`import`) | ||
expect(workerContent).not.toMatch(`export`) | ||
|
||
// shared worker should have all imports resolved and no exports | ||
expect(sharedWorkerContent).not.toMatch(`import`) | ||
expect(sharedWorkerContent).not.toMatch(`export`) | ||
|
||
// chunk | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap-inline/assets/my-worker` | ||
) | ||
expect(content).toMatch(`new Worker("data:application/javascript;base64`) | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap-inline/assets/possible-ts-output-worker` | ||
) | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap-inline/assets/worker-nested-worker` | ||
) | ||
expect(content).toMatch( | ||
`new SharedWorker("/iife-sourcemap-inline/assets/my-shared-worker` | ||
) | ||
|
||
// inlined | ||
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`) | ||
expect(content).toMatch(`window.Blob`) | ||
|
||
expect(workerNestedWorkerContent).toMatch( | ||
`new Worker("/iife-sourcemap-inline/assets/sub-worker` | ||
) | ||
}) | ||
} else { | ||
// Workaround so that testing serve does not emit | ||
// "Your test suite must contain at least one test" | ||
test('true', () => { | ||
expect(true).toBe(true) | ||
}) | ||
} | ||
|
||
function getSourceMapUrl(code: string): string { | ||
const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g | ||
const results = regex.exec(code) | ||
|
||
if (results && results.length >= 2) { | ||
return results[1] | ||
} | ||
return null | ||
} |
1 change: 1 addition & 0 deletions
1
packages/playground/worker/__tests__/sourcemap-inline/vite.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('../../vite.config-sourcemap')('inline') |
131 changes: 131 additions & 0 deletions
131
packages/playground/worker/__tests__/sourcemap/sourcemap-worker.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import fs from 'fs' | ||
import path from 'path' | ||
import { untilUpdated, isBuild, testDir } from '../../../testUtils' | ||
import { Page } from 'playwright-chromium' | ||
|
||
if (isBuild) { | ||
const assetsDir = path.resolve(testDir, 'dist/iife-sourcemap/assets') | ||
// assert correct files | ||
test('sourcemap generation for web workers', async () => { | ||
const files = fs.readdirSync(assetsDir) | ||
// should have 2 worker chunk | ||
expect(files.length).toBe(25) | ||
const index = files.find((f) => f.includes('main-module')) | ||
const content = fs.readFileSync(path.resolve(assetsDir, index), 'utf-8') | ||
const indexSourcemap = getSourceMapUrl(content) | ||
const worker = files.find((f) => /^my-worker\.\w+\.js$/.test(f)) | ||
const workerContent = fs.readFileSync( | ||
path.resolve(assetsDir, worker), | ||
'utf-8' | ||
) | ||
const workerSourcemap = getSourceMapUrl(workerContent) | ||
const sharedWorker = files.find((f) => | ||
/^my-shared-worker\.\w+\.js$/.test(f) | ||
) | ||
const sharedWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, sharedWorker), | ||
'utf-8' | ||
) | ||
const sharedWorkerSourcemap = getSourceMapUrl(sharedWorkerContent) | ||
const possibleTsOutputWorker = files.find((f) => | ||
/^possible-ts-output-worker\.\w+\.js$/.test(f) | ||
) | ||
const possibleTsOutputWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, possibleTsOutputWorker), | ||
'utf-8' | ||
) | ||
const possibleTsOutputWorkerSourcemap = getSourceMapUrl( | ||
possibleTsOutputWorkerContent | ||
) | ||
const workerNestedWorker = files.find((f) => | ||
/^worker-nested-worker\.\w+\.js$/.test(f) | ||
) | ||
const workerNestedWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, workerNestedWorker), | ||
'utf-8' | ||
) | ||
const workerNestedWorkerSourcemap = getSourceMapUrl( | ||
workerNestedWorkerContent | ||
) | ||
const subWorker = files.find((f) => /^sub-worker\.\w+\.js$/.test(f)) | ||
const subWorkerContent = fs.readFileSync( | ||
path.resolve(assetsDir, subWorker), | ||
'utf-8' | ||
) | ||
const subWorkerSourcemap = getSourceMapUrl(subWorkerContent) | ||
|
||
expect(files).toContainEqual(expect.stringMatching(/^index\.\w+\.js\.map$/)) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^my-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^my-shared-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^possible-ts-output-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^worker-nested-worker\.\w+\.js\.map$/) | ||
) | ||
expect(files).toContainEqual( | ||
expect.stringMatching(/^sub-worker\.\w+\.js\.map$/) | ||
) | ||
|
||
// sourcemap should exist and have a data URL | ||
expect(indexSourcemap).toMatch(/^main-module\.\w+\.js\.map$/) | ||
expect(workerSourcemap).toMatch(/^my-worker\.\w+\.js\.map$/) | ||
expect(sharedWorkerSourcemap).toMatch(/^my-shared-worker\.\w+\.js\.map$/) | ||
expect(possibleTsOutputWorkerSourcemap).toMatch( | ||
/^possible-ts-output-worker\.\w+\.js\.map$/ | ||
) | ||
expect(workerNestedWorkerSourcemap).toMatch( | ||
/^worker-nested-worker\.\w+\.js\.map$/ | ||
) | ||
expect(subWorkerSourcemap).toMatch(/^sub-worker\.\w+\.js\.map$/) | ||
|
||
// worker should have all imports resolved and no exports | ||
expect(workerContent).not.toMatch(`import`) | ||
expect(workerContent).not.toMatch(`export`) | ||
|
||
// shared worker should have all imports resolved and no exports | ||
expect(sharedWorkerContent).not.toMatch(`import`) | ||
expect(sharedWorkerContent).not.toMatch(`export`) | ||
|
||
// chunk | ||
expect(content).toMatch(`new Worker("/iife-sourcemap/assets/my-worker`) | ||
expect(content).toMatch(`new Worker("data:application/javascript;base64`) | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap/assets/possible-ts-output-worker` | ||
) | ||
expect(content).toMatch( | ||
`new Worker("/iife-sourcemap/assets/worker-nested-worker` | ||
) | ||
expect(content).toMatch( | ||
`new SharedWorker("/iife-sourcemap/assets/my-shared-worker` | ||
) | ||
|
||
// inlined | ||
expect(content).toMatch(`(window.URL||window.webkitURL).createObjectURL`) | ||
expect(content).toMatch(`window.Blob`) | ||
|
||
expect(workerNestedWorkerContent).toMatch( | ||
`new Worker("/iife-sourcemap/assets/sub-worker` | ||
) | ||
}) | ||
} else { | ||
// Workaround so that testing serve does not emit | ||
// "Your test suite must contain at least one test" | ||
test('true', () => { | ||
expect(true).toBe(true) | ||
}) | ||
} | ||
|
||
function getSourceMapUrl(code: string): string { | ||
const regex = /\/\/[#@]\s(?:source(?:Mapping)?URL)=\s*(\S+)/g | ||
const results = regex.exec(code) | ||
|
||
if (results && results.length >= 2) { | ||
return results[1] | ||
} | ||
return null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('../../vite.config-sourcemap')(true) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.