带有 Gatsby js 和 window 的 Scrollmagic 在部署时未定义

Scrollmagic with Gatsby js and window undefined upon deploy

我的 Gatsby 站点无法部署到 Netlify,因为 WebpackError: ReferenceError: window is not defined

我试过:

  1. if(window !== undefined) 中包装 return 语句检查哪个不起作用
  2. 在我的 index.js 中添加一个 require 语句:if (typeof window !== 'undefined') { require('scrollmagic') require('scrollmagic-plugin-gsap') } 没有用

我注意到导入语句 import Scrollmagic from 'scrollmagic' 已经导致了错误,因为我曾经尝试在没有任何 scrollmagic 代码的情况下部署站点,除了导入。

我的组件的 scrollmagic 部分是这样的(我在这个例子中删除了一些不相关的变量赋值):

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>
    )
}

我该怎么做?

我看不到你在代码中调用 window 的位置,但解决所有问题的方法是在使用 [=14] 呈现组件后延迟 window 调用=](在基于 class 的组件中)或在基于无状态的组件中具有空 deps ([]) 的 useEffect。所以,你需要做这样的事情:

  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 条件。

但是,如果您使用的第三方库使用 window 来完成它们的工作,则需要将此代码段放入 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 文档:

One solution is to customize your webpack configuration to replace the offending module with a dummy module during server rendering.

来源:https://www.gatsbyjs.org/docs/debugging-html-builds/#fixing-third-party-modules