Загрузка сторонней библиотеки JavaScript

#javascript #vue.js #webpack

#javascript #vue.js #webpack

Вопрос:

Я разработал проигрыватель веб-радио, используя Vue Cli. Теперь мне нужно добавить новую функциональность, используя внешнюю библиотеку (она предназначена для обработки аудиорекламы), и эта библиотека должна обслуживаться с удаленного хоста. Я не могу просто загрузить библиотеку и импортировать ее локально.

Настройка

В моем приложении Vue у меня есть несколько компонентов, и в одном из них у меня есть аудио-тег, обрабатывающий воспроизведение радио. Мне нужно определить нажатие на кнопку воспроизведения, загрузить объявление, воспроизвести его, а затем перейти к обычному воспроизведению радио.

Подходы, которые я пробовал

  1. Загрузка внешней библиотеки в index.html досье. Это работает, но я не могу взаимодействовать с плеером, загружаемым в Vue. Например, если я попытаюсь прослушать событие воспроизведения в index.html file ( audio.addEventListener("play", onPlay); , я просто получаю «аудио не определено» в веб-консоли.
  2. Загрузка внешней библиотеки в разделе mounted () моего компонента:
 const triton = document.createElement('script')
triton.setAttribute('src', '//sdk.listenlive.co/web/2.9/td-sdk.min.js')
document.head.appendChild(triton)
this.initPlayerSDK()
triton.onload = () => {
  let player = new TDSdk(this.tdPlayerConfig)
  console.log(player)
}
  

Проблема с этим подходом заключается в том, что после npm run serve того, как я получу сообщение 'TDSdk' is not defined , которое имеет полный смысл. Я загружаю внешний JS-файл, но webpack не интерпретирует его содержимое, потому что это делается во время выполнения. Я должен добавить внешний в свой vue.config.js , но это тоже не работает:

vue.config.js

 const path = require('path')

module.exports = {
  publicPath: './',
  /*configureWebpack: {
    externals: {
      tdSdk: 'tdSdk'
    }
  },*/
  chainWebpack: config => {
    config.module
    .rule('images')
    .test(/.(png|jpe?g|gif|webp)(?.*)?$/)
    .use('url-loader')
    .loader('file-loader') // not url-loader but file-loader !
    .tap((options) => { // not .option() but .tap(options...)
      // modify the options...
      options.name = 'img/[name].[ext]'
      return options
    }),
    config.externals([
      {
        'tdSdk': 'TDSdk'
      },
    ])
  },
  css: {
    loaderOptions: {
      sass: {
        sassOptions: {
        includePaths: [path.resolve(__dirname, './node_modules/compass-mixins/lib')]
        }
      }
    }
  },
  externals: {
    tdSdk: 'TDSdk'
  }
}
  

MyComponent.vue

 import tdSdk from 'tdSdk'
  

Комментарии:

1. Добавьте скрипт в HTML, если хотите import работать.

2. Дело в том, что код должен обслуживаться из исходного источника, а не с локального хоста.

3. Здесь нет противоречия. Измените его. См. cli.vuejs.org/guide/html-and-static-assets.html

4. Спасибо за ваш ответ. Я думаю, что я не понимаю, как это сделать. Я импортировал библиотеку регулярно <script> tag and it doesn’t work. Если есть способ сделать это с помощью синтаксиса <% %>, я его не понимаю.

5. Нет необходимости в синтаксисе <%. index.html обычный HTML-код, его можно редактировать. Да, обходной путь заключается в том, как это можно сделать в данном случае. Однако в этом случае вам вообще не нужно динамически добавлять скрипт и сопоставлять его с экспортом.

Ответ №1:

Моим решением было загрузить библиотеку в public/index.html файл, а затем дождитесь загрузки DOM, чтобы я мог добавить прослушиватель событий к уже загруженному аудиоэлементу:

 document.addEventListener('DOMContentLoaded', function() {
var playControl = document.getElementById('playIcon');
playControl.addEventListener("click", onPlay);
}
  

Затем в хранилище Vuex мне нужно было получить доступ к переменным, определенным в javascript, расположенным в index.html . Для этого я устанавливаю window.adState (var, который я использую) в качестве глобального var в моем файле хранилища:

 Vuex.Store.prototype.$adState = window.adState
  

Наконец, в моих действиях / мутациях я использовал this.$adState для проверки его содержимого:

 playPause ({ commit, dispatch }) {
console.log('AdState', this.$adState)
(...)
}
  

Ответ добавлен от имени OP.

Ответ №2:

Импорт не может быть разрешен во время оценки скрипта, поскольку TDSdk global недоступен. Скрипт, который динамически добавляется head , загружается асинхронно, поэтому в любом случае будет условие гонки.

<script> необходимо добавлять динамически, если задействовано динамическое поведение или, например, условие, или разработчик не контролирует макет страницы. Для статического скрипта общедоступный интерфейс проекта Vue CLI index.html может быть изменен:

   <body>
    <div id="app"></div>
    <script src="//sdk.listenlive.co/web/2.9/td-sdk.min.js"></script>
    <!-- built files will be auto injected -->
  </body>
  

Пакет приложений оценивается после скрипта, и ожидается, что глобальный будет доступен там.

Внешние файлы обычно используются для пакетов, которые были заменены на пакеты, загруженные извне, обычно из CDN. Поскольку tdSdk это не настоящий пакет и у него нет перспектив для замены на него, нет смысла сопоставлять его с глобальным и импортировать. Его можно просто использовать как TDSdk глобальный в приложении.

Комментарии:

1. Я полностью понимаю вашу точку зрения. Единственное, что TDSdk недоступен из приложения, это сообщение об ошибке, которое я получаю. Мой обходной путь заключается в том, чтобы дождаться готовности DOM (Vue полностью загружен), а затем добавить прослушиватель событий в элемент <audio>: document.addEventListener(‘DOMContentLoaded’, function() { document.getElementById(‘audio’).addEventListener(«play», onPlay); }); Дело в том, что при таком подходе я не могу взаимодействовать с объектом ad, поскольку он недоступен из моего приложения.