Почему Tone JS не играет хорошо в компоненте Svelte?
Я довольно новичок в 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, но я успешно использовал Tone JS во многих других проектах (в том числе внутри React и т. Д.) Без каких-либо проблем.
Что может быть причиной этого? И как начать использовать ToneJS в моем приложении Svelte? (Упаковано / транспортировано с использованием Rollup)
3 ответа
Это происходит потому, что 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 года:
Если вы пытаетесь использовать Tone.js в проекте svelte 4/sveltekit 1.0, вот один потенциальный обходной путь, хотя и за счет SSR:
Создавать+layout.ts
в любом маршруте, который вы пытаетесь использовать (например, src/routes/+layout.ts) и установите:
export const ssr = false;
Это должно предотвратить запуск Tone.js в узле путем отключения шага ssr, который необходим, поскольку он зависит от API веб-аудио.