带有 Gatsby js 和 window 的 Scrollmagic 在部署时未定义
Scrollmagic with Gatsby js and window undefined upon deploy
我的 Gatsby 站点无法部署到 Netlify,因为 WebpackError: ReferenceError: window is not defined
我试过:
- 在
if(window !== undefined)
中包装 return 语句检查哪个不起作用
- 在我的 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
我的 Gatsby 站点无法部署到 Netlify,因为 WebpackError: ReferenceError: window is not defined
我试过:
- 在
if(window !== undefined)
中包装 return 语句检查哪个不起作用 - 在我的 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