以下组件AudioPlayer
-基于react-media-player
,在Gatsby / React开发环境中效果很好。但是,将其构建到React SSR中一直是个地狱。
AudioPlayer
依赖于实例化window
对象,Node.js无法使用该对象。因此,我不得不使用Gatsby的自定义Webpack配置来检测媒体播放器,并将null加载器放入混合中。效果很好:
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /react-media-player/,
use: loaders.null(),
},
],
},
})
}
}
但是当您尝试通过Webpack进行构建时,现在出现错误:
WebpackError:TypeError:无法解构以下项的属性
CurrentTime
'undefined'或'null'。
这很有意义,因为我们刚删除了react-media-player
,其中包含CurrentTime
。因此,如何确保Webpack不会尝试破坏此组件中的controls
对象? (ES6中的other answers on S.O. regarding conditional destructuring对我来说毫无意义,因此请慢慢解释一下:)>
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
以下组件AudioPlayer-基于react-media-player,在Gatsby / React开发环境中效果很好。但是,将其构建到React SSR中一直是一件令人头疼的事。 AudioPlayer依赖于...
对于将来的Google员工/感兴趣的人,要解决此问题,最终的解决方案需要花很多时间才能实现。我将逐步讲解它的所有工作,希望这对其他人有帮助: