Сценарий не работает, когда он связан с динамическим импортом вместо простого тега <script> - PullRequest
0 голосов
/ 23 октября 2019

У меня есть домашний аудиоплеер, который отлично работает на моем веб-сайте, когда он связан со страницей с помощью обычного тега script:

<head>
  …
  <script type="application/javascript" src="/static/js/player.js"></script>
</head>

Сам скрипт написан на простом JS без каких-либо библиотек, фреймворков,и т.д. Вот демонстрация того, как это работает : вы нажимаете треугольник, игрок начинает играть;Здесь нет ничего особенного. (Это может не работать в некоторых старых браузерах, но сейчас это не имеет значения.)

Однако проигрыватель сломался, если я связал его с динамическим импортом (в браузерах, которые поддерживают этот вид импорта). В HTML другой скрипт index.js связан вместо player.js, и этот index.js импортирует player.js:

// index.js
console.log('index.js is running…');
import('/static/js/player.js');

Вот вторая демонстрация этой версии ,протестировано в Chrome для Windows и Safari на macOS, все браузеры и ОС имеют последние версии на момент публикации.

player.js, похоже, загружается и выполняется. Когда я включаю console.log() s в него, он выводит их именно там, где я ожидаю;Я также не обнаружил никаких отличий во время выполнения от предыдущей версии с отладчиком в Dev Tools.

Но аудиоплеер в этом случае не работает. Если вы нажмете треугольник, то вместо запуска плеера вы получите только прямую ссылку на файл MP3. Первоначально, это было предполагаемое поведение, когда скрипт не был загружен или был сломан;но я не могу понять, что именно ломается в этом случае.

Сценарий player.js абсолютно одинаков в обоих случаях;единственное отличие заключается в добавлении динамического импорта во втором случае. Пожалуйста, помогите мне найти, что с ним не так.

Ответы [ 2 ]

1 голос
/ 26 октября 2019

Вы помещаете свои js-файлы в заголовки, вот где происходит волшебство. Если вы прочитаете файл player.js , вы увидите, что ваш проигрыватель отвечает на DOMContentLoaded

new Effect({  // container
behavior: `
  $window
    DOMContentLoaded
      _.init
`,
prop
....

В первом примере ваш веб-сайт в основном перестает загружаться до player.js загружен, потому что вы поместили его в заголовок, player.js способен связать событие с DOMContentLoaded . Затем, после того как весь исходный HTML-документ был полностью загружен и проанализирован, событие DOMContentLoaded сработало, и ваш проигрыватель смог запустить

В вашем втором примере, http://dev.chebykin.ru/player/02/. Событие DOMContentLoaded будет запущено после выполнения сценария для файла player.js , поскольку вы загрузили файл с помощью команды импорта. Несмотря на то, что ваш сценарий по-прежнему может связывать событие DOMContentLoaded , но оно уже сработало, поэтому оно не дает никакого эффекта

Вы можете просто попробовать вручную запустить событие триггера снова на консоли Chrome, и вы увидитеплеер работает нормально с помощью этого скрипта

window.dispatchEvent(new Event('DOMContentLoaded'))
0 голосов
/ 25 октября 2019

Поскольку старые версии JS не имели импорта, но с 2015 года (ES6) у JS был стандарт модулей ES6 для импорта модулей в NodeJS.

Я бы попробовал один из этих двух разных подходов, чтобы он заработал:

1 - Динамическая загрузка с тегами скрипта из файла index.js, например:

Index.js:

function dynamicallyLoadScript(jsFilePath) {
    var js = document.createElement("script");

    js.type = "text/javascript";
    js.src = jsFilePath;

    document.body.appendChild(js);
    //or: document.head.appendChild(script); 
}

dynamicallyLoadScript("/static/js/player.js");

2 - Или используйте импорт новых модулей ES6 (не забудьте сохранить player файл с расширением mjs !):

<script type="module">
  import { player } from './static/js/player.mjs';
  player();
</script>

Player.mjs:

export function player() {
   //Your code here
}

Кроме того, вы можете использовать некоторые инструменты, такие какBabel или Webpack, если вам нужна совместимость со старыми браузерами. Вы можете найти дополнительную информацию здесь: Как включить файл JavaScript в другой файл JavaScript?

Надеюсь, это поможет!

...