-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
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
support worklet #11543
Comments
hm.. I think |
yep, expect for the audio worklet, that should work. |
for "base" audio there is https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/audioWorklet for custom thing there is a workaround to
index.js
in parser.worker => |
@vankop Maybe we can support it out of box as I written in the issue 😄 |
@evilebottnawi we can add this to defaults https://github.com/webpack/webpack/blob/master/lib/dependencies/WorkerPlugin.js#L31 @sokra approve? |
Which stage is the worklet spec? Is this final or still a proposal? |
|
I've been trying to create a AudioWorklet with Webpack 5 for 3 hours and I cannot seem to find any way to make it work. Even by trying to add everything I could think of in
With Webpack 4 I can use https://github.com/reklawnos/worklet-loader but it's not compatible with Webpack 5. It would be useful to have a modular way to indicate that we want to create a new JS chunk when importing and return this chunk URL instead of the actual JS import. For now, I'm going to stick with Webpack 4 as it seems that there is no way to use Worklets with Webpack 5. |
@geekuillaume Can you provide reproducible test repo? |
My bad, worklet-loader is working with Webpack 5 (with some deprecation warnings). |
@geekuillaume Anyway can you provide example of the problem, I want to fix it, we should avoid |
@evilebottnawi Here is the test case: https://github.com/geekuillaume/webpack-audioworklet-testcase If you look at the console, you'll see this error:
The |
@geekuillaume Do you use |
It is running on localhost, there is no protection about loading external module on local hosts. You can verify this as there is no warning or error in the console. |
@geekuillaume Sorry you need https for this feature, try to use this feature without webpack - the same problem |
@evilebottnawi My bad, there was an error in my code, I was not waiting for the promise returned by We can close this issue but it would be great to document this in the webpack doc. |
@geekuillaume Let's keep open, because we need to add tests and improve docs after this |
If you use Using Using (notice the 2nd example fails due to the |
@skratchdot For this you need to specify |
I don't know how to do that. I've tried a few things and keep seeing errors. When I try examples higher up in the thread I see |
Yep, I will update example in the next future |
Sorry for delay, I think should work: {
module: {
rules: [
{
test: /\.js$/,
parser: {
// For other use the same
worker: ["CSS.paintWorklet.addModule()", "..."]
}
}
]
},
} @chenxsan I think we can create small guide for worklets on docs site |
@alexander-akait Sorry for a dumb question, but how would you specify an audio worklet parser.worker? |
|
Could somebody provide a complete example or link to some documentation please? |
@alexander-akait ah okay. I wasn't sure if the configs cited in #17212 had to be added explicitly, or if worklets are supported by default as long as webpack@5.85.0+ is installed (looks like I have 5.86.0). I think I can use react-app-rewired to modify the webpack configs? Tried it, but it didn't seem to do anything. I might be doing it wrong, though. I've updated the sandbox repo with my changes if you'd like to take a look. |
@thurinus if you open an issue on CRA we can help them land this change if needed. But yeah it is just a webpack config update so that should work for you. |
@thurinus try this: module.exports = function override(config, env) {
//do stuff with the webpack config...
config.module.parser = {
javascript: {
worker: [
"*context.audioWorklet.addModule()",
"*audioWorklet.addModule()",
// *addModule() is not valid syntax
"...",
],
}
};
return config;
}; Better to define syntax globally, because you can already have rules for After this I put
So we are in valid scope 😄 |
@alexander-akait I assume you got it working in the sandbox just by changing the
Was there anything else you had to change? Somewhat tangential, but I also wasn't able to add |
@thurinus weird, maybe cache? Becaue you even don't have |
@alexander-akait I had to clear |
@thurinus weird, give me a time to look at this again |
@thurinus Oh, the problem is only for const ReactRefreshPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
module.exports = function override(config, env) {
if (env === "development") {
config.plugins = config.plugins.filter(plugin => plugin.constructor.name !== 'ReactRefreshPlugin');
config.plugins.push(new ReactRefreshPlugin({
overlay: false,
exclude: /(node_modules)|(.+\.worklet\.(ts|js)$)/i,
include: /\.([cm]js|[jt]sx?|flow)$/i
}));
}
config.module.parser = {
javascript: {
worker: [
"*context.audioWorklet.addModule()",
"*audioWorklet.addModule()",
// *addModule() is not valid syntax
"...",
],
}
};
return config;
}; it will fix a problem, but there is another problem - autoreloading, CRA has:
So they forcibly disable page reloading in |
@alexander-akait it works! Thanks so much for digging into CRA's scripts to find the issue. Yeah CRA has its problems, and looks like people are generally moving away from it now. I don't know if it's worth raising this with them to update their configs. This'll be a good solution for existing CRA apps - I'll update my sandbox and leave it up for anyone else who might stumble on this looking for the same answers. |
So is there a complete, reliable solution? None of your comments were helpful. Just some random chunks of code who knows how to get together. Maybe my issue is that I use project type module? |
I have tried so many workarounds / new features that were merged, none of them allowed me to import external files. I always ended up with The only thing that worked for me is to set up copy-webpack-plugin on my workerLib directory and use the vanilla API to load workers and import files.... |
The syntax specified in webpack/webpack.js.org#6869 appears to work for me but I'm hitting an issue with
I can make that error go away by setting |
@Johennes Sorry for delay, sounds like a bug, I can fix it, do you use |
@marcusletric Sorry for delay too, can you provide a code where you try to use them, because we have a lot of tests and I think you have something strange in your configuration, thank you |
@alexander-akait Regarding the To reproduce:
The current solution to support worklets is to use the Web Worker plugin with an additional syntax matching. This results in My initial thought was that we could maybe do this:
I'm not sure yet how webpack could solve this. Fetch, XMLHttpRequest and dynamic imports are not available. But WebPack might need to load chunks dynamically. |
@mrmachine Thank you your feedback and report, I will look at this soon |
@Danielku15 I see your problem, we should not apply Why do you use There are three problems:
Current workaround - exclude worklet chunks in I think we need to implement I am fine if someone will send PR |
Shorty - if you have:
Check your |
Greetings, everyone, I really do hope you'll be able to assist me with this exact problem. I've tried everything described here, but still receive: Prerequisites:
It seems I've tried everything I could've found in the net and thought myself with zero result. Link to the repo in the current state: https://github.com/LoserAntbear/telenes
Really hope to find some help, since I'm desperately stuck. I was able to compile it using Which, it seems, means, that despite it was compiled it is not being loaded for some reason. [UPD1]: Interestingly enough, it appeared, that after adjusting webpack config's parser it actually works. Webpack-dev-server DOES serve the static worklet Although it does not want to process imports within that file, I receive I expect it happens since worklet is being served and treated as |
On one hand it is primarily to show the problem that the worklet support is not capable of dynamically loading chunks. The problem does not appear in the tests due to the small size and not using any node_modules. In reality I am having a setup like described in here. (expand me)I have a shared foundation for my main library code and background workers/worklets. And this shared foundation might also pull further dependencies from external libraries. flowchart LR
app.js-- import -->mylib.main.js
mylib.main.js-- new Worker -->mylib.worker.js
mylib.main.js-- import -->mylib.shared.js
mylib.main.js-- audioworklet.addModule -->mylib.worklet.js
mylib.worker.js-- import -->mylib.shared.js
mylib.worklet.js-- import -->mylib.shared.js
mylib.shared.js-- import --> vendor[some npm libs from node_modules]
I've seen in various scenarios that some code (mylib.shared.js) was duplicated into multiple chunks. To optimize the sizes of chunks and avoid the duplication I deliberatly move some files into a dedicated chunk. If WebPack is used together with frameworks like Angular, React or Vue, I think it is easily possible to end up in a scenario where a worklet might need to pull some other chunks or dependencies (e.g. the typical vendor.js).
Unfortunately I have to agree that this might be the only workaround unless we or the standard comitees invent something which allows loading other files into the worklet context. But I fear it might be against the goals developers want to achieve with WebPack. Unfortunately many people assume still that workers or worklets might be just some simple small code snippets. But in reality (considering background canvas rendering and audio synthesizing) those workers might be doing very complex tasks. And for this also the worklets/workers might require/import again other modules and dependencies. For worklets this means: Duplicating all dependencies and modules into the worklet file instead of benefiting from single chunks being cached and reused by the browser.
It is great to here that you made progress. I am currently working on an approach where at least I can import 1 level of dependencies into the worklet by using an inline blob worklet and static imports. I am not there yet but progressing. Maybe it also helps you getting things running: class AlphaTabWorkletUrl {
static create(url: URL) { return url; }
}
function createWebPackWorklet(context: AudioContext) {
// ./alphaTab.worklet is rewritten to ./alphaTab.worklet.mjd in the typescript transpilation
// before things go into webpack
const workletUrl = AlphaTabWorkletUrl.create(new URL('./alphaTab.worklet', import.meta.url));
const sharedPartUrl = AlphaTabWorkletUrl.create(new URL('./alphaTab.core', import.meta.url)); // TODO: just need the URL of the chunk containing alphaTab.core, not an own worker bootstrapping script.
const workletCode = `
debugger;
import * as shared from ${JSON.stringify(sharedPartUrl)};
import * as worklet from ${JSON.stringify(workletUrl)};
`;
const workletBlob = new Blob([workletCode], { type: "application/javascript; charset=utf-8" });
const workletBlobUrl = window.URL.createObjectURL(workletBlob);
return context.audioWorklet.addModule(workletBlobUrl);
}
/*
combined with:
module: {
rules: [
{
test(path) {
return path.includes('alphaTab.worklet.mjs');
},
parser: {
worker: [
"AlphaTabWorkletUrl.create()",
'...'
]
}
}
]
}
*/ |
Yeah, anyway if you have ideas how we can solve it feel free to send any PRs, I see the problem, I suggested excluding this from any optimization so that it would at least work out of the box without problems |
@Danielku15 Thanks for the heads up! So great thanks and big credit to @leviance for the effort and making it work. |
This comment was marked as outdated.
This comment was marked as outdated.
@alexander-akait I have a draft change to the worker plugin ready which works for my library to import some dependencies into the worklet before launching the original worklet. But to finalize it properly I'd need some guidance. I'm lacking a bit the knowledge how to do things correctly within WebPack. The current change: The change does following:
Clarifications I need:
Of course alternatively you can adopt my idea and write a plugin/change in your preferred style. I'm happy to test anything in my project. |
@Danielku15 Looks intresting, can you send this PR and adopt existing worklet tests for it?
Good idea, I like it
Can you clarify?
it is not trivial task |
I mean this part of the code which is quite messy: https://github.com/Danielku15/webpack/blob/765efb28a6122c0a3bc97690b2d0438de4fe3c12/lib/dependencies/WorkerPlugin.js#L454-L493 ModuleDependencies can overwrite source file ranges with custom strings but I need to know how I can (efficiently) adopt parts of the original sources to be used in the string I generate in my ModuleDependency. The inefficient solution I found is to copy known ranges from the My goal: We have an expression of Talking in placeholders we have on a
Any suggestion how the new worklet plugin should deal with the import? The |
I prepared a draft of a new plugin which I tested successfully in my project. The hurdles to actually contribute to WebPack feel still a bit high, maybe with community effort we can complete this PR (unittest, manual tests in some projects, writing website/docs,...). |
Workaround for now since
|
Feature request
What is the expected behavior?
Working with
worklet
s out of boxWhat is motivation or use case for adding/changing the behavior?
Why not?
How should this be implemented in your opinion?
Like
web workers
, maybe under optionsAre you willing to work on this yourself?
Not right now
The text was updated successfully, but these errors were encountered: