Share Posted June 2, 2020 Hi guys, I am using webpack as the tool to compile my JS. ScrollTrigger works amazing in the local dev setup, no errors. Unfortunately, when I run the `yarn build` command, the production code logs a warning Invalid property scrollTrigger set to {trigger: ".pSection", scrub: true} Missing plugin? gsap.registerPlugin() The issue is that it IS registered, and it's working fine in dev mode. This is the exact example as on your codepen import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger.js"; gsap.registerPlugin(ScrollTrigger); gsap.to(".pContent", { yPercent: -100, ease: "none", scrollTrigger: { trigger: ".pSection", // start: "top bottom", // the default values // end: "bottom top", scrub: true, }, }); gsap.to(".pImage", { yPercent: 50, ease: "none", scrollTrigger: { trigger: ".pSection", // start: "top bottom", // the default values // end: "bottom top", scrub: true, }, }); Steps to reproduce: I have used custom and the official facebook starterkit and they both have the same issue. npx create-react-app scrolltrigger open INDEX.JS remove all code (we don't want any react there anyway) paste following code: import "./index.css"; import { gsap } from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger.js"; gsap.registerPlugin(ScrollTrigger); gsap.to(".pContent", { yPercent: -100, ease: "none", scrollTrigger: { trigger: ".pSection", // start: "top bottom", // the default values // end: "bottom top", scrub: true, }, }); gsap.to(".pImage", { yPercent: 50, ease: "none", scrollTrigger: { trigger: ".pSection", // start: "top bottom", // the default values // end: "bottom top", scrub: true, }, }); run yarn (or npm) start , everything works fine, no errors run yarn build , (run the code that's in the build folder. e.g. python -m SimpleHTTPServer 8812 Now you'll see errors I am not sure how this is happening, happy to help if you have any clues.... Attached the zip with all the filesscrolltrigger.zip Cheers, Joris P.S I have tried setting the name as per , but that's not allowed and won't compile. See the Pen JjYPQpN by GreenSock (@GreenSock) on CodePen Link to comment Share on other sites More sharing options...
Share Posted June 2, 2020 Yeah, sorry, setting the name in certain environments won't work. I've revised the beta file with a different solution. https://assets.codepen.io/16327/ScrollTrigger.min.js As far as I know, the original file would only have problems in IE - were you seeing issues elsewhere? 1 Link to comment Share on other sites More sharing options...
Author Share Posted June 2, 2020 Hey jack, thanks for your response! The issue is that ScrollTrigger is causing those errors in a production build. In any browser! Link to comment Share on other sites More sharing options...
Share Posted June 2, 2020 As a temporary solution (until we push 3.3.1 out, which will likely be within the next few days), try adding this right after registering the plugin: gsap.core.globals("ScrollTrigger", ScrollTrigger); Does that help? 2 1 Link to comment Share on other sites More sharing options...
Author Share Posted June 2, 2020 Thanks Jack, yes, that seems to do the trick on the prod build! Much appreciated 1 Link to comment Share on other sites More sharing options...
Share Posted June 2, 2020 (edited) I am having issues in a similar setup, though I appear to be getting a different error: # /node_modules/gsap/ScrollTrigger.js:517 # export var ScrollTrigger = /*#__PURE__*/function () { # ^^^^^^ # # SyntaxError: Unexpected token 'export' I am trying to create a staggered letter reveal of a word that is triggered when the component has entered the viewport. I have the following in my file as I already found and tried this work around: import PropTypes from "prop-types"; import { useRef, useEffect } from "react"; import { gsap, CSSPlugin } from "gsap"; import ScrollTrigger from "gsap/ScrollTrigger"; import styled from "styled-components"; gsap.registerPlugin(ScrollTrigger); gsap.core.globals("ScrollTrigger", ScrollTrigger); const AnimatedH1 = ({ content }) => { const letters = content.split(""); // create array of letters let letterRefs = useRef([]); // initial array of letter refs let triggerPointRef = useRef(null); // initial trigger point ref const tl = gsap.timeline(); // timeline // this map outputs each letter and assignes it a unique ref, updating our letterRefs const outputLetters = () => letters.map((letter, i) => ( <Letter key={i} ref={el => (letterRefs.current[i] = el)}> {letter} </Letter> )); // On mount of the component stagger the letters on the timeline using the // trigger point ref to trigger the timeline useEffect(() => { tl.staggerFrom( letterRefs.current, 0.6, { scrollTrigger: triggerPointRef.current, y: 200, opacity: 0, }, 0.02 ); }, [letterRefs]); return ( // assign our wrapping div as the trigger for the timeline scrollTrigger <div ref={el => (triggerPointRef.current = el)}> <WordContainer>{outputLetters()}</WordContainer> </div> ); }; Any ideas what could be causing that? Love the plugin by the way, it's amazing! 👏 Edited June 2, 2020 by littledotchris added fuller file contents Link to comment Share on other sites More sharing options...
Share Posted June 2, 2020 2 hours ago, littledotchris said: I am having issues in a similar setup, though I appear to be getting a different error: # /node_modules/gsap/ScrollTrigger.js:517 # export var ScrollTrigger = /*#__PURE__*/function () { # ^^^^^^ # # SyntaxError: Unexpected token 'export' That means your environment doesn't support es modules. You can try umd modules. import { gsap } from "gsap/dist/gsap"; import { ScrollTrigger } from "gsap/dist/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); Also, you don't need to import the CSSPlugin. Where did you get that from? Need to stop incorrect information from spreading. 2 Link to comment Share on other sites More sharing options...
Share Posted June 2, 2020 Also note that we recommend using the GSAP 3 way of formatting GSAP code, i.e. no staggerFrom and putting the duration inside of the vars parameter in the code above. For more information see the GSAP 3 migration guide: 1 Link to comment Share on other sites More sharing options...
Share Posted June 3, 2020 On 6/2/2020 at 1:28 PM, OSUblake said: That means your environment doesn't support es modules. You can try umd modules. import { gsap } from "gsap/dist/gsap"; import { ScrollTrigger } from "gsap/dist/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); Also, you don't need to import the CSSPlugin. Where did you get that from? Need to stop incorrect information from spreading. Thank you for your response! It looks that way, though I had a GSAP timeline working with the ES module approach, it was only adding in the ScrollTrigger plugin that introduced the issue I am currently seeing. So I am fairly sure ES modules are supported in my environment. As for the CSSPlugin, It was left over by accident, apologies for that... I was previously importing Timeline and appeared that the Timeline uses CSSPlugin under the hood so required it? Fairly sure I found that tip on the forum. (Let's hope I was reading the correct GSAP version at that time). Thank you for the link Zach! Let's get my syntax in order 😅 1 Link to comment Share on other sites More sharing options...
Share Posted June 3, 2020 (edited) Ok so, for arguments sake I am now using the correct syntax, and umd modules, leaving my file looking like this: import PropTypes from "prop-types"; import { useRef, useEffect } from "react"; import { gsap } from "gsap/dist/gsap"; import { ScrollTrigger } from "gsap/dist/ScrollTrigger"; import styled from "styled-components"; gsap.registerPlugin(ScrollTrigger); const AnimatedH1 = ({ content }) => { const letters = content.split(""); let letterRefs = useRef([]); let triggerPointRef = useRef(null); const tl = gsap.timeline({ scrollTrigger: { trigger: triggerPointRef.current, scrub: true, start: "top top", end: "+=100%", }, }); const outputLetters = () => letters.map((letter, i) => ( <Letter key={i} ref={ el => (letterRefs.current[i] = el) }> {letter} </Letter> )); useEffect(() => { tl.from(letterRefs.current, { duration: 1, y: 200, opacity: 0, stagger: 0.02, }); }, [letterRefs]); return ( <div ref={ el => (triggerPointRef.current = el) }> <WordContainer>{ outputLetters() }</WordContainer> </div> ); }; I appear to still have errors, though now I am getting: # Please gsap.registerPlugin(ScrollTrigger) # TypeError: _toArray is not a function I have also tried having `gsap.core.globals("ScrollTrigger", ScrollTrigger); ` after the plugin registration, but the errors persist. Scratching my head a little on this one. Thanks for all your help so far, any ideas what I might be experiencing? Edited June 3, 2020 by littledotchris spelling Link to comment Share on other sites More sharing options...
Share Posted June 3, 2020 2 hours ago, littledotchris said: As for the CSSPlugin, It was left over by accident, apologies for that... I was previously importing Timeline and appeared that the Timeline uses CSSPlugin under the hood so required it? Fairly sure I found that tip on the forum. (Let's hope I was reading the correct GSAP version at that time). Yeah, it was probably from a previous version. 2 hours ago, littledotchris said: It looks that way, though I had a GSAP timeline working with the ES module approach, it was only adding in the ScrollTrigger plugin that introduced the issue I am currently seeing. So I am fairly sure ES modules are supported in my environment. Depending on your setup, it might have been importing umd from "gsap/dist/gsap" even though you had "gsap. But I don't think you mentioned your setup. If you are doing SSR, then you need to register by checking if the window exists, or inside useEffect or componentDidMount. 1 Link to comment Share on other sites More sharing options...
Share Posted June 3, 2020 Yeah, I bet that the document.documentElement isn't available when you register the plugin. I'm gonna make a few tweaks internally to allow that to be delayed which may solve the issue for you as long as when the ScrollTrigger is actually created, the document.documentElement exists. Or perhaps Blake's suggestion will resolve it all anyway 1 Link to comment Share on other sites More sharing options...
Share Posted June 3, 2020 (edited) I honestly love this forum, you guys offer some of the best support I've come across. 😅 You are of course correct, my particular setup is a Next.js app, so either SSR pages or Static pages that are pre-rendered on the server. (Don't know why I didn't mention that earlier 🤦♂️) I've gotten it to work using Blake's useEffect suggestion, though I needed to check for window even inside the useEffect, makes sense to me. For anyone else's benefit, here's the final working code: useEffect(() => { // make sure we're in browser land for gsap plugin registration if (typeof window !== "undefined") { // register gsap ScrollTrigger plugin gsap.registerPlugin(ScrollTrigger); // Set up timeline const tl = gsap.timeline({ scrollTrigger: { trigger: triggerPointRef.current, scrub: true, start: "top", }, }); // Configure the timeline animation tl.from(letterRefs.current, { duration: 1, y: 200, opacity: 0, stagger: 0.02, }); } }, [letterRefs]); And for all the people finding this via google, here's a bunch of words... React / Next.js gsap ScrollTrigger, Please gsap.registerPlugin(ScrollTrigger) TypeError: _toArray is not a function. There is probably a more elegant solution than this, because thinking about it, this useEffect lives inside this particular component, there could be multiple of these on the page together, so it seems to me like registering multiple instances of ScrollTrigger is probably going to cause issues / not be best practice. Am I right in my thinking guys? Perhaps a useEffect in the top level app component to register the plugin once so it's available to use in child components that call it? Any suggestions welcome 😄 Thank you Zach, Jack & Blake! Edited June 3, 2020 by littledotchris Rubber ducked myself and found an issue with my approach. 3 Link to comment Share on other sites More sharing options...
Share Posted June 3, 2020 Yay! Thanks for sharing the solution...and even sprinkling in some extra keywords for SEO juice that'll help others find it Happy tweening/scrolling! 1 Link to comment Share on other sites More sharing options...
Share Posted June 4, 2020 Do you know if I'm likely to run into any issues "registering the plugin" in a component that will be used multiple times on the page? At the moment it seems to work fine, i'm just wondering if this is not optimal, given that I will likely have a lot of components using the ScrollTrigger plugin on page at the same time, and each component instance runs the gsap.registerPlugin(ScrollTrigger) when it's mounted. Link to comment Share on other sites More sharing options...
Author Share Posted June 4, 2020 Nope, that's not an issue. You can register plugins as many times as you want. No drawbacks in doing it multiple times. 3 Link to comment Share on other sites More sharing options...
Share Posted June 4, 2020 Thank you for clarifying, if that's the case then I think this is a pretty good solution. Cheers for all your help guys, this plugin is amazing! 😁 Link to comment Share on other sites More sharing options...
Share Posted June 4, 2020 I have the similar error when building static Nuxt app 1 Link to comment Share on other sites More sharing options...
Share Posted June 4, 2020 gsap.core.globals("ScrollTrigger", ScrollTrigger); this does help Link to comment Share on other sites More sharing options...
Share Posted June 5, 2020 Hi 👋 I also had the issue using a simple create-react-app in production and this code worked for me. gsap.core.globals("ScrollTrigger", ScrollTrigger); I'll wait until 3.3.1 to test again and take this out. Link to comment Share on other sites More sharing options...
Share Posted February 1 Hi, I have the same issue with my webpack 5 configuration, I'm using. gsap 3.11.4 and I don't have any problem in development mode but when I build my project, I have the same error. I added the line below and it's working now, I did not have this problem in other projets. gsap.core.globals("ScrollTrigger", ScrollTrigger); I already used this webpack configuration and I don't have any problem before. Does anyone have an idea what is the problem and how to fix it ? Thanks EDIT: Its seems that the problem came from TerserPlugin 3 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now