我们的应用程序构建在下一个之上,我们目前正在从脚本处理器将我们的音频记录引擎迁移到audio。(当然,具有向后兼容性)过渡的一部分也升级到Webpack 5。我们同时使用Workers和Audio。在切换到Webpack 5之前,它附带了对工人的本地支持,我们使用了工频插件。这两种方法都非常有效,但是我们不能再依赖它了,因为它使用的是过时的Webpack的API,接下来是它自己捆绑的Webpack 4和5,它们似乎没有向后兼容性。
现在的挑战是让这些工作与Webpack 5捆绑在一起。第一个问题来自未定义的web工作者的全局范围。可以通过将config.output.globalObject设置为"(typeof self !== 'undefined' ? self : this)"来解决此问题。一旦工作人员开始工作,下一个问题就会出现在试图捆绑worklet代码时。目前,Webpack 5不支持worklet导入,但它们公开了解析器配置,根据这个Github问题,解析器配置可以用来告诉webpack将其作为工作人员加载。除非您在通过config.output.publicPath = "/_next/";加载块时设置audioContext.audioWorklet.addModule(...),否则Next将失败,代码将使用Uncaught TypeError: Cannot read property 'webpackChunk_N_E' of undefined崩溃。如果我们检查包含捆绑的worklet代码块,我们将看到这个支柱是以以下方式使用的:
var chunkLoadingGlobal = (typeof self !== 'undefined' ? self : this)["webpackChunk_N_E"] = (typeof self !== 'undefined' ? self : this)["webpackChunk_N_E"] || [];
var parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);
.
.
.
(typeof self !== 'undefined' ? self : this)["webpackHotUpdate_N_E"] = function...很明显,AudioWorkletGlobalScope既没有self也没有this,所以这就是为什么它不太好的原因。
所以问题是,如何解决这个问题?尽管现在即使在Safari默认的情况下,音频Worklet似乎仍然很少得到Next和Webpack的关注。(自14.5起)
下面是表示我们当前状态的代码段。(我们使用打字本)
next.config.js
module.exports = withPlugins([...], {
future: {webpack5: true},
webpack: (config, options) => {
config.output.globalObject = `(typeof self !== 'undefined' ? self : this)`;
config.output.publicPath = "/_next/";
config.resolve = {
...config.resolve,
alias: {
...config.resolve.alias,
"audio-worklet": path.resolve(__dirname, "src/util/audio-worklet")
}
}
config.module.parser = {
...config.module.parser,
javascript: {
worker: ["AudioWorklet from audio-worklet", "..."]
}
}
config.output.chunkFilename = options.isServer
? `${options.dev ? "[name].[hash]" : "[name].[chunkhash]"}.js`
: `static/chunks/${options.dev ? "[name].[hash]" : "[name].[chunkhash]"}.js`;
return config;
}
});src/util/audio-worklet.ts
export const AudioWorklet = (url: URL) => {
return url as unknown as string;
};.../audio-context.ts
import { AudioWorklet } from "audio-worklet";
const audioContext = new AudioContext();
audioContext.audioWorklet.addModule(new AudioWorklet(new URL("path/to/processor.worklet.ts", import.meta.url)));.../audio-worklet-processor.worklet.ts
// import statements for utility code
class Processor extends AudioWorkletProcessor {
// Your run of the mill processor code
}
registerProcessor("processor", Processor);资料来源:
更新
经过很长时间的挖掘,这个问题似乎是webpack在块中导入脚本引起的。具体来说,当我们试图导入任何非平凡的代码,比如提交,或者使用babel认为使用其shims所必需的数据结构时,Webpack注入了installChunk函数,该函数使用importScripts,这显然不受AudioWorklets的支持。这还插入了上面导致Uncaught TypeError: Cannot read property 'webpackChunk_N_E' of undefined的代码。
这里有一个回购,一个一个地复制:https://github.com/thecynicalpaul/test-audio-worklet-webpack5 (nmp i,然后是npm run dev)
发布于 2022-03-07 22:20:12
我自己回答,因为我们找到了一个临时的解决方案。
这个问题之所以发生,是因为Webpack 5中的URL加载器将工作文件视为web工作者文件。这意味着,上下文是由工作人员组成的,它将尝试使用importScripts这样的API,这些API显然是不受支持的。
我们研究到的解决方案是,对与工作单元相关的任何块禁用块分割,从而有效地消除使用importScripts的需要。
(在next.config.js的webpack函数中)
if (!options.isServer && !options.dev) {
config.optimization.splitChunks = {
chunks: (chunk) => {
// this may vary widely on your loader config
if (chunk.name && chunk.name.includes("worklet")) {
return false;
}
return true;
}
}
}出于显而易见的原因,这并不是大计划中最好的解决方案,webpack的团队目前正在寻找更好的方法来解决这个问题。
发布于 2022-03-06 21:25:48
我也在努力解决这个问题,并且发现删除webpack的所有注入的客户端代码可以解决这个问题,而不会出现明显的倒退。这是一种黑客行为,但很有效:
{
test: /webpack-dev-server\\client/,
loader: "null-loader"
}https://stackoverflow.com/questions/67444578
复制相似问题