Scrollmagi c с Гэтсби js и окном, не определенным при развертывании - PullRequest
1 голос
/ 02 апреля 2020

Мой сайт Гэтсби не может быть развернут на Netlify из-за WebpackError: ReferenceError: window is not defined

, который я пробовал:

  1. Заключение операторов возврата в if(window !== undefined) проверок, которые не сделали t work
  2. Помещение в мой индекс оператора require. js: if (typeof window !== 'undefined') { require('scrollmagic') require('scrollmagic-plugin-gsap') }, который не работал

Я заметил, что оператор import import Scrollmagic from 'scrollmagic' уже вызывает ошибку потому что я однажды попытался развернуть сайт без кода scrollmagi c, за исключением импорта.

Часть моего компонента scrollmagi c выглядит следующим образом (в этом примере я удалил некоторые нерелевантные назначения переменных):

import React, { useRef, useEffect } from 'react'
import ScrollMagic from "scrollmagic"
import { TweenMax, TimelineMax, Power3, TweenLite, TimelineLite } from "gsap"
import { ScrollMagicPluginGsap } from "scrollmagic-plugin-gsap";

const Techstack = () => {
  ScrollMagicPluginGsap(ScrollMagic, TweenMax, TimelineMax);

  const techs = useRef()
  const trigger = useRef()


  useEffect(() => {
    let controller = new ScrollMagic.Controller()
    const techitems = techs.current.children
    const tl = new TimelineMax
    for (let i = 0; i < techitems.length; i++) {
      new ScrollMagic.Scene({
        triggerElement: techitems[i],
      })
        .setTween(TweenLite.from(techitems[i], 1, { opacity: 0, x: -300, ease: Power3.easeOut }))
        .addTo(controller)
    }
  }, [])


    return (
      <TechstackContainer ref={trigger} id="trigger">
        <ContentWrapper ref={techs}>
          <StyledTechstackText>
            Ich baue Webseiten und Apps, am liebsten mit:
        </StyledTechstackText>
          {stack.map(el => {
            return <TechItem>{el}</TechItem>
          })}
        </ContentWrapper>
      </TechstackContainer>
    )
}

Как бы я go об этом?

1 Ответ

2 голосов
/ 02 апреля 2020

Я не вижу, куда вы звоните window в своем коде, но способ решить все эти проблемы - отложить вызов window после того, как компонент отрендерен с использованием componentDidMount (в компоненте на основе классов ) или useEffect с пустыми значениями deps ([]) в компоненте без сохранения состояния. Итак, вам нужно сделать что-то вроде этого:

  useEffect(() => {
    if(typeof window !== undefined){
      let controller = new ScrollMagic.Controller()
      const techitems = techs.current.children
      const tl = new TimelineMax
      for (let i = 0; i < techitems.length; i++) {
        new ScrollMagic.Scene({
          triggerElement: techitems[I],
        })
          .setTween(TweenLite.from(techitems[i], 1, { opacity: 0, x: -300, ease: Power3.easeOut }))
          .addTo(controller)
      }
    }
  }, [])

Обратите внимание на условие typeof window !== undefined.

Однако, если вы используете сторонние библиотеки, которые используют окно, чтобы сделать их вещи, вам нужно будет поместить этот фрагмент в ваш gatsby-node:

exports.onCreateWebpackConfig = ({ actions, loaders, getConfig, stage }) => {
  const config = getConfig();

  config.module.rules = [
    // Omit the default rule where test === '\.jsx?$'
    ...config.module.rules.filter(
      rule => String(rule.test) !== String(/\.jsx?$/)
    ),

    // Recreate it with custom exclude filter
    {
      ...loaders.js(),

      test: /\.jsx?$/,

      // Exclude all node_modules from transpilation, except for 'swiper' and 'dom7'
      exclude: modulePath =>
        /node_modules/.test(modulePath)
    },
  ];

  if (stage.startsWith('develop') && config.resolve) {
    config.resolve.alias = {
      ...config.resolve.alias,
      'react-dom': '@hot-loader/react-dom'
    }
  }
};

В соответствии с документацией Gatsby:

Одним из решений является настройка вашего веб-пакета конфигурация для замены неисправного модуля на фиктивный модуль во время рендеринга сервера.

Источник: https://www.gatsbyjs.org/docs/debugging-html-builds/#fixing -third-party-modules

...