greensock / GSAP

GSAP (GreenSock Animation Platform), a JavaScript animation library for the modern web
https://gsap.com
19.85k stars 1.72k forks source link

What is the correct way to load GSAP with Webpack? #168

Closed bishopZ closed 8 years ago

bishopZ commented 8 years ago

When I load GSAP with webpack, I get the error _doc = document; document is not defined.

This page suggests several ways to "shim" modules. But none of them are working for me.

This forum thread suggests some ways to shim the module to be compatible with ES6 import statements and works if "global" is defined in the node environment.

I don't see a clear solution. Any help appreciated.

bishopZ commented 8 years ago

Adding this to the beginning of the TweenMax.js var window = global.parent || {} , navigator = { userAgent: "" } , dummyElement = { style: {}, getElementsByTagName: function() { return [] } } , document = global.document || { createElement: function() { return dummyElement } }; and this to the end module.exports = TweenMax;

Works locally, but of course I can't modify the TweenMax source code on the server as it is downloaded from NPM. :(

jackdoyle commented 8 years ago

The module.exports = TweenMax shouldn't be necessary - that happens internally for you. As for editing things on the server, if you're using NPM doesn't that just put the GSAP files in the node_modules/gsap directory?

I'm curious - is your goal to use GSAP outside the browser environment ultimately?

bishopZ commented 8 years ago

I am using GSAP in a browser. Webpack runs in the Node environment to bundle the JS into a single file. Webpack uses AMD, ES6 and CommonJS module loading patterns but does not allow access to global variables such as document or window.

bishopZ commented 8 years ago

Please don't take this the wrong way. Webpack is the most popular build library for advanced javascript development. React and Angular development all but require it. Please tell me there is some way to load GSAP in webpack without hacking the source code.

bishopZ commented 8 years ago

Fwiw Jack, I admire your code a lot and am honored to be on a comment thread with you. Let me know if there is any way I can help here.

jackdoyle commented 8 years ago

Oh, absolutely. I have used Webpack and know of plenty of others who are doing so successfully with GSAP - that's why I was asking about your particular scenario. It seemed odd that it was giving you any trouble. You are using the latest version of GSAP, 1.19.0, right? And the latest Webpack? How exactly are you importing the GSAP classes? Perhaps you can send me instructions for reproducing the issue you're running into?

bishopZ commented 8 years ago

Yah, I believe other people have it working. I am not doing anything special, but I may have made a fundamental error.

// package.json
"engines": {
    "node": "=6.2.2",
    "npm": "=3.9.5"
},
"dependencies": {
    "gsap": "1.19.0",
    "react": "^15.0.2",
    "react-dom": "^15.0.2",
    "react-gsap-enhancer": "0.2.2",

// webpack 2.12.0 config
module: {
    loaders: [
      {
        test: /\.js?$|\.jsx?$/,
        loaders: ['babel?' + JSON.stringify(hmrConfig), 'eslint'],
        exclude: /node_modules/
      },

// App.jsx
import GSAP from 'react-gsap-enhancer';
import {TimelineMax} from 'gsap';

At that point I start getting errors when webpack attempt to build.

/git/client/node_modules/gsap/src/uncompressed/TweenMax.js:2600
                        _doc = document,
                               ^

ReferenceError: document is not defined
    at Function.<anonymous> (/git/client/node_modules/gsap/src/uncompressed/TweenMax.js:2600:11)
    at [object Object].check (/git/client/node_modules/gsap/src/uncompressed/TweenMax.js:6015:61)
    at new Definition (/git/client/node_modules/gsap/src/uncompressed/TweenMax.js:6039:10)
    at window._gsDefine (/git/client/node_modules/gsap/src/uncompressed/TweenMax.js:6044:12)
    at Array.<anonymous> (/git/client/node_modules/gsap/src/uncompressed/TweenMax.js:2553:11)
    at /git/client/node_modules/gsap/src/uncompressed/TweenMax.js:7820:9
    at Object.<anonymous> (/git/client/node_modules/gsap/src/uncompressed/TweenMax.js:7831:3)
    at Module._compile (module.js:413:34)
    at Module._extensions..js (module.js:422:10)
    at Object.require.extensions.(anonymous function) [as .js] (/git/client/node_modules/babel-register/lib/node.js:166:7)
bishopZ commented 8 years ago

My other JSX modules are and have been working fine. I am not having any issues with React or Babel. I did however have a very similar issue with Bootstrap requiring access to the window object. I also spoke with someone on the Webpack Gitter Chat that was having a similar issue with the library Backbone needing access to window.

I am guessing that there is some Webpack magic that allows this. The Webpack docs suggest that the imports-loader may allow this, but I have not found a working example of the imports-loader.

Their docs suggest that I should be able to load GSAP something like this

import GSAP from 'imports?window=window,document=document!gsap';

The chatter from Webpack Gitter Chat and I have both attempted this. Him with backbone and me with GSAP. In both cases the error is "Cannot find module" which means that imports-loader did not run. I have created an issue on the imports-loader repo.

You could argue that since the issue happens with multiple libraries that it is not specifically a GSAP thing. Although, based on the forum thread I mentioned earlier, other GSAP users are also having this issue, and the currently published solution is less than ideal.

jackdoyle commented 8 years ago

A few questions:

  1. Your post seems to indicate you're using webpack version 2.12.0. Was that a typo? If I'm reading things correctly, the latest stable release is 1.13.1 and I didn't see webpack listed at all in your dependencies (I assume it's there, but you just didn't include it in your post)
  2. What exactly is the hmrConfig variable mentioned in your webpack config?

I'm trying to replicate your exact scenario and I'm having a tough time with the limited details. Is there any chance you could provide more details so that I can very easily just run a couple NPM commands and replicate the issue?

Did you verify that the GSAP version is actually 1.19.0? I see that you've got it in your package.json as that version - I'm just making sure you've double-checked that it's truly that version in your local build (like if you didn't npm update after changing the version in the package.json or something).

Lastly, have you tried anything without the react-gsap-enhancer? Just wondering if that's causing any problems.

bishopZ commented 8 years ago
  1. You are correct- I looked at the wrong thing "webpack": "^1.12.9",
  2. I looked into that a lot too. It is the Hot Media Reload react magic. It's not causing the issue.
  3. Yes, I would like to arrive at a concise example of the issue. I don't have time to put that together right now, but will eventually. As near as I have been able to hunt, the crux of the issue is very simple. I actually find it easiest to reproduce with Bootstrap, though it is the same issue as with Greensock (slightly different error messages). Webpack + Babel (ES2015) + import bootstrap. I documented that problem on stack. With Bootstrap the error happens without React even running. I have not tried that with GSAP. The simplest example I have seen with GSAP is Webpack + Babel + React + GSAP = error on build.
  4. react-gsap-enhancer is working fine (even without gsap), and gsap still errors without react-gsap-enhancer.
  5. double checked the version * VERSION: 1.19.0 * DATE: 2016-07-16.

My current work around is to load GSAP and Bootstrap as Script tags. Then access them as window.TimelineMax from within the React components. This gets me back up and running, but all of my scripts are bundled by webpack, except those two, heh.

Let me know your ideas!

bishopZ commented 8 years ago

I just realized that the codebase I started with is published online. That should have all the details you ever wanted. :)

jackdoyle commented 8 years ago

Oh wow, that's huge. Over 20,000 files in the node_modules directory alone. Certainly not a reduced test case :) I've gotta run to a meeting, but I'll try to look at this later. I'd recommend starting with a simpler case that just gets the basics going (React, Babel, GSAP, Webpack) and then add stuff until it breaks. I don't have a lot of time to pull this whole thing apart, though, to isolate what's going on in your setup. So many variables. Again, a reduced test case would be super helpful. I know you said you'd try to put one together at some point. No rush.

jackdoyle commented 8 years ago

Sorry about the delayed response. Been traveling. I peeked at the project and unfortunately I just don't have time to dig into the 20,000+ files and isolate the issue for you. I can definitely say that many others have confirmed that they can use GSAP just fine in Webpack/Node/React apps, and I've done it myself so I'm not quite sure what's causing the issue in your particular setup. I really wish I had a better answer for you. Have you had any success creating a reduced test case?

bishopZ commented 8 years ago

It will take me a few weeks to free up. Thanks for vigilance.

bishopZ commented 8 years ago

I created a simple WebPack template without React. Bootstrap has the same problems, but GSAP does not. This tells me three things:

I can safely track the problem down from here. Many thanks for your help and I will post again if I discover more.

jackdoyle commented 8 years ago

Thanks for reporting back, @bishopZ. I'm happy to hear it wasn't a GSAP-related issue. Best of luck to you. Let us know if you need anything else. Happy tweening!

ralphholzmann commented 8 years ago

@bishopZ did you ever figure out the issue that caused this? I'm running into this exact error right now, and I don't have bootstrap in my project.

bishopZ commented 8 years ago

What is the issue: Webpack provides very limited access to the window object. Some libraries do not play well with some configurations. What is the solution: Only thing I have found is to load the offending libraries with SCRIPT tags, taking them outside the control of Webpack. For me this includes Bootstrap and GSAP, but any library could be the cause.

ralphholzmann commented 8 years ago

thanks @bishopZ -- I appreciate it.

Ideally gsap should be able to initialize and export itself without actually referencing browser builtins like the document and window but i assume that wouldn't be a trivial task at this point.

thanks again

jshrssll commented 7 years ago

I'm running into this same problem using a universal Angular 2 application that renders on the server. So given that there is no "document" or "window" on the server, I get a bunch of compiler errors.

jackdoyle commented 7 years ago

I made a few tweaks to the beta [uncompressed] file at https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/TweenMax-latest-beta.js - does that work better for you?

jshrssll commented 7 years ago

@jackdoyle almost there... Now I'm just getting the following error

ERROR calling setTween() due to missing Plugin 'animation.gsap'. Please make sure to include plugins/animation.gsap.js

I'm importing animation.gsap with this import 'imports-loader?define=>false!scrollmagic/scrollmagic/uncompressed/plugins/animation.gsap';

jackdoyle commented 7 years ago

Let's stick with the other thread instead of bouncing back-and-forth. As I mentioned there, the error you're referencing seems to be related to ScrollMagic, not GSAP. Maybe reach out to its author.

rcwestlake commented 7 years ago

@jackdoyle I'm having this issue as well using Webpack + Babel + React. What thread is the one you mentioned?

jackdoyle commented 7 years ago

@rcwestlake which issue in particular? The edits I made are in the newly-published 1.19.1 version. Is that what you're using?

rcwestlake commented 7 years ago

@jackdoyle document was not defined when I ran a build command using Node. I was using 1.19.0, when I switched to 1.19.1, the build worked. Thanks!

jackdoyle commented 7 years ago

Ah, that explains it :)