Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
joris-rotteveel

ScrollTrigger and webpack prod build

Recommended Posts

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

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? 

  • Like 1
Link to comment
Share on other sites

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

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? 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Thanks Jack,

 

yes, that seems to do the trick on the prod build! Much appreciated :D

  • Thanks 1
Link to comment
Share on other sites

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 by littledotchris
added fuller file contents
Link to comment
Share on other sites

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.

 

  • Like 2
Link to comment
Share on other sites

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:

 

  • Like 1
Link to comment
Share on other sites

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 😅

  • Like 1
Link to comment
Share on other sites

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 by littledotchris
spelling
Link to comment
Share on other sites

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.

 

 

 

  • Like 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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 by littledotchris
Rubber ducked myself and found an issue with my approach.
  • Like 3
Link to comment
Share on other sites

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!

  • Like 1
Link to comment
Share on other sites

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

Nope, that's not an issue. You  can register plugins as many times as you  want. No drawbacks in doing it multiple times.

  • Like 3
Link to comment
Share on other sites

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

I have the similar error when building static Nuxt app

 

 

Screenshot 2020-06-04 at 14.56.34.png

  • Like 1
Link to comment
Share on other sites

gsap.core.globals("ScrollTrigger", ScrollTrigger);

this does help

Link to comment
Share on other sites

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×