Почему 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 веб-аудио.

Другие вопросы по тегам