Условное разрушение объекта JS для сборки Gatsby / React SSR - PullRequest
0 голосов
/ 24 октября 2018

Следующий компонент, 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...