-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17212 from webpack/feat-support-custom-syntax
feat: introduce a new syntax for worklets - `*context.audioWorklet.addModule()`
- Loading branch information
Showing
10 changed files
with
303 additions
and
1 deletion.
There are no files selected for viewing
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
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,202 @@ | ||
// This is a pseudo-worklet, it is not a real worklet, but it is used to test the worker logic. | ||
// Real worklets do not have this API. | ||
|
||
it("should allow to create a paintWorklet worklet", async () => { | ||
let pseudoWorklet = await CSS.paintWorklet.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should allow to create a layoutWorklet worklet", async () => { | ||
let pseudoWorklet = await CSS.layoutWorklet.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should allow to create a animationWorklet worklet", async () => { | ||
let pseudoWorklet = await CSS.animationWorklet.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should allow to create a audioWorklet worklet", async () => { | ||
let context = new AudioContext(); | ||
let pseudoWorklet = await context.audioWorklet.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should allow to create a paintWorklet worklet using '?.'", async () => { | ||
let pseudoWorklet = await CSS?.paintWorklet?.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should allow to create a audioWorklet worklet #2", async () => { | ||
let audioWorklet = (new AudioContext()).audioWorklet; | ||
let pseudoWorklet = await audioWorklet.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should allow to create a audioWorklet worklet #3", async () => { | ||
let context = { | ||
foo: { | ||
bar: new AudioContext() | ||
} | ||
}; | ||
let pseudoWorklet = await context.foo.bar.audioWorklet.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should allow to create a audioWorklet worklet using '?.'", async () => { | ||
let context = new AudioContext(); | ||
let pseudoWorklet = await context?.audioWorklet?.addModule(new URL("./worklet.js", import.meta.url)); | ||
|
||
pseudoWorklet = new pseudoWorklet(); | ||
|
||
expect(pseudoWorklet.url).not.toContain("asset-"); | ||
|
||
pseudoWorklet.postMessage("ok"); | ||
|
||
const result = await new Promise(resolve => { | ||
pseudoWorklet.onmessage = event => { | ||
resolve(event.data); | ||
}; | ||
}); | ||
expect(result).toBe("data: OK, thanks"); | ||
|
||
await pseudoWorklet.terminate(); | ||
}); | ||
|
||
it("should not create a audioWorklet worklet", async () => { | ||
let workletURL; | ||
|
||
const barContext = new class Foo { | ||
constructor() { | ||
this.audioWorklet = { | ||
addModule(url) { | ||
workletURL = url.toString(); | ||
|
||
return undefined; | ||
} | ||
} | ||
} | ||
} | ||
|
||
await barContext.audioWorklet.addModule(new URL("./worklet-asset-1.js", import.meta.url)); | ||
|
||
expect(workletURL).toContain("asset-"); | ||
}); | ||
|
||
it("should not create a audioWorklet worklet", async () => { | ||
let workletURL; | ||
|
||
const barContext = new class Foo { | ||
constructor() { | ||
this.unknownWorklet = { | ||
addModule(url) { | ||
workletURL = url.toString(); | ||
|
||
return undefined; | ||
} | ||
} | ||
} | ||
} | ||
|
||
await barContext.unknownWorklet.addModule(new URL("./worklet-asset-2.js", import.meta.url)); | ||
|
||
expect(workletURL).toContain("asset-"); | ||
}); |
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,3 @@ | ||
export function upper(str) { | ||
return str.toUpperCase(); | ||
} |
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,33 @@ | ||
let outputDirectory; | ||
|
||
module.exports = { | ||
moduleScope(scope) { | ||
const FakeWorker = require("../../../helpers/createFakeWorker")({ | ||
outputDirectory | ||
}); | ||
|
||
// Pseudo code | ||
scope.AudioContext = class AudioContext { | ||
constructor() { | ||
this.audioWorklet = { | ||
addModule: url => Promise.resolve(FakeWorker.bind(null, url)) | ||
}; | ||
} | ||
}; | ||
scope.CSS = { | ||
paintWorklet: { | ||
addModule: url => Promise.resolve(FakeWorker.bind(null, url)) | ||
}, | ||
layoutWorklet: { | ||
addModule: url => Promise.resolve(FakeWorker.bind(null, url)) | ||
}, | ||
animationWorklet: { | ||
addModule: url => Promise.resolve(FakeWorker.bind(null, url)) | ||
} | ||
}; | ||
}, | ||
findBundle: function (i, options) { | ||
outputDirectory = options.output.path; | ||
return ["main.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,6 @@ | ||
var supportsWorker = require("../../../helpers/supportsWorker"); | ||
var supportsOptionalChaining = require("../../../helpers/supportsOptionalChaining"); | ||
|
||
module.exports = function (config) { | ||
return supportsWorker() && supportsOptionalChaining(); | ||
}; |
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,27 @@ | ||
/** @type {import("../../../../").Configuration} */ | ||
module.exports = { | ||
output: { | ||
assetModuleFilename: "asset-[name][ext]", | ||
filename: "[name].js" | ||
}, | ||
target: "web", | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.[cm]?js$/, | ||
parser: { | ||
worker: [ | ||
"CSS.paintWorklet.addModule()", | ||
"CSS.layoutWorklet.addModule()", | ||
"CSS.animationWorklet.addModule()", | ||
"*context.audioWorklet.addModule()", | ||
"*context.foo.bar.audioWorklet.addModule()", | ||
"*audioWorklet.addModule()", | ||
// *addModule() is not valid syntax | ||
"..." | ||
] | ||
} | ||
} | ||
] | ||
} | ||
}; |
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 @@ | ||
function test1() {} |
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 @@ | ||
function test2() {} |
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,4 @@ | ||
onmessage = async event => { | ||
const { upper } = await import("./module"); | ||
postMessage(`data: ${upper(event.data)}, thanks`); | ||
}; |
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