Следующий компонент, AudioPlayer
- на основе react-media-player
прекрасно работает в среде Gatsby / React dev.Но было чертовски трудно заставить его встроиться в React SSR.
AudioPlayer
полагается на объект window
для создания экземпляра, который недоступен Node.js.Итак, мне пришлось использовать пользовательскую конфигурацию Gatsby Webpack, чтобы обнаружить медиаплеер и добавить ноль загрузчик в микс.Это работает достаточно хорошо:
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /react-media-player/,
use: loaders.null(),
},
],
},
})
}
}
Но когда вы пытаетесь собрать через Webpack, теперь я получаю ошибку:
WebpackError: TypeError: Невозможно уничтожить свойство CurrentTime
of 'undefined 'или' null '.
Это имеет смысл, поскольку мы только что обнулили react-media-player
, который содержит CurrentTime
.Итак, как мне убедиться, что Webpack НЕ пытается деструктурировать объект controls
в этом компоненте?( другие ответы на SO относительно условной деструктуризации в ES6 не имеют для меня никакого смысла, поэтому идите медленно с любыми объяснениями):
import React, { Component } from 'react'
import { Media, Player, controls } from 'react-media-player'
const { CurrentTime, SeekBar, Duration, Volume, PlayPause, MuteUnmute } = controls
let panner = null
class AudioPlayer extends Component {
componentDidMount() {
const audioContext = new (window.AudioContext || window.webkitAudioContext)()
panner = audioContext.createPanner()
panner.setPosition(0, 0, 1)
panner.panningModel = 'equalpower'
panner.connect(audioContext.destination)
const source = audioContext.createMediaElementSource(this._player.instance)
source.connect(panner)
panner.connect(audioContext.destination)
}
_handlePannerChange = ({ target }) => {
const x = +target.value
const y = 0
const z = 1 - Math.abs(x)
panner.setPosition(x, y, z)
}
render() {
return (
<div>
{ typeof window !== 'undefined' && Media &&
<Media>
<div>
<Player
ref={c => this._player = c}
src={this.props.src}
useAudioObject
/>
<section className="media-controls">
<div className="media-title-box">
<PlayPause className="media-control media-control--play-pause"/>
<div className="media-title-content">
<div className="media-title">{ this.props.mediaTitle }</div>
<div className="media-subtitle">{ this.props.mediaSubtitle }</div>
</div>
</div>
<div className="media-controls-container">
<CurrentTime className="media-control media-control--current-time"/>
<SeekBar className="media-control media-control--volume-range"/>
<Duration className="media-control media-control--duration"/>
</div>
<div className="media-sound-controls">
<MuteUnmute className="media-control media-control--mute-unmute"/>
<Volume className="media-control media-control--volume"/>
</div>
</section>
</div>
</Media>
}
</div>
)
}
}
export default AudioPlayer