#javascript #vue.js #webpack
#javascript #vue.js #webpack
Вопрос:
Я разработал проигрыватель веб-радио, используя Vue Cli. Теперь мне нужно добавить новую функциональность, используя внешнюю библиотеку (она предназначена для обработки аудиорекламы), и эта библиотека должна обслуживаться с удаленного хоста. Я не могу просто загрузить библиотеку и импортировать ее локально.
Настройка
В моем приложении Vue у меня есть несколько компонентов, и в одном из них у меня есть аудио-тег, обрабатывающий воспроизведение радио. Мне нужно определить нажатие на кнопку воспроизведения, загрузить объявление, воспроизвести его, а затем перейти к обычному воспроизведению радио.
Подходы, которые я пробовал
- Загрузка внешней библиотеки в index.html досье. Это работает, но я не могу взаимодействовать с плеером, загружаемым в Vue. Например, если я попытаюсь прослушать событие воспроизведения в index.html file (
audio.addEventListener("play", onPlay);
, я просто получаю «аудио не определено» в веб-консоли. - Загрузка внешней библиотеки в разделе 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, поскольку он недоступен из моего приложения.