针对Gatsby / React SSR构建的JS对象的条件分解

问题描述 投票:1回答:1

以下组件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依赖于...

reactjs webpack gatsby destructuring server-side-rendering
1个回答
0
投票

对于将来的Google员工/感兴趣的人,要解决此问题,最终的解决方案需要花很多时间才能实现。我将逐步讲解它的所有工作,希望这对其他人有帮助:

© www.soinside.com 2019 - 2024. All rights reserved.