我对 Svelte 相当陌生(我正在使用版本 2,直到版本 3 正确发布),并且我正在构建一个旨在进行一些音频分析 (FFT) 的网站。因此,我将古老的 ToneJS 库 (http://tonejs.github.io/) 合并到我的组件之一中。
出于某种原因,仅仅导入 ToneJS 就足以使整个应用程序崩溃。
这是我的 Svelte 组件的全部内容:
<h2>Pitch analyser</h2>
<script>
import Tone from 'tone';
</script>
这会导致错误:
Tone.js:7 Uncaught TypeError: Cannot assign to read only property 'listener' of object '#<AudioContext>'
at t.Context.set (Tone.js:7)
at t.Listener.<anonymous> (Tone.js:7)
at Function.e.getContext (Tone.js:7)
at new t.Listener (Tone.js:7)
at Object.<anonymous> (Tone.js:7)
at Object.<anonymous> (Tone.js:7)
at i (Tone.js:1)
at Object.<anonymous> (Tone.js:7)
at i (Tone.js:1)
at Tone.js:1
这可能不是 Svelte 特有的,但我已经在许多其他项目(包括 React 等)中成功使用了 Tone JS,没有任何问题。
这可能是什么原因造成的?以及如何开始在我的 Svelte 应用程序中使用 ToneJS? (使用 Rollup 打包/编译)
发生这种情况是因为 Rollup 作为原生 JavaScript 模块捆绑器,必须将所有 JS 视为严格模式(因为 JavaScript 模块始终是严格的),即使它们是从旧格式转换而来。
不幸的是,Tone.js 正在做违反严格模式的事情(分配给不可写属性)。我建议在该回购协议上提出问题;严格模式更快、更安全,并且确实没有理由不支持严格模式环境。
同时,您可以通过将 Tone.js 作为常规
<script>
标记并在应用程序中将其作为全局引用来解决此问题。
将
intro:
线放入 rollup.config.js
为我解决了这个问题:
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/bundle.js',
// Added this line:
intro: 'var global = typeof self !== undefined ? self : this;'
},
2023 更新:
如果您尝试在 svelte 4 / sveltekit 1.0 项目中使用 Tone.js,这里有一个潜在的解决方法,尽管以 SSR 为代价:
在您尝试使用的任何路线(即 src/routes/+layout.ts)中创建
+layout.ts
并设置:
export const ssr = false;
这应该通过禁用 ssr 步骤来阻止 Tone.js 在节点中运行,这是必要的,因为它依赖于 Web Audio API。