Jump to content
Search Community

1.19.0 ES6 imports working example?

supermoos test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I've tried to do this:
 

import {TweenLite, TimelineLite} from 'gsap';

I'm using JSPM and SystemJS to load modules, however it just always loads TweenMax.js and not TweenLite.js and TimelineLite.js - do you have an example of a working setup, doesn't have to be with JSPM.

Link to comment
Share on other sites

Yes, we're hoping to start work on rewriting things in ES6 soon, but in the mean time to allow those import statements to work we just made sure that TweenMax adds each global class to its exports. So when you say "from 'gsap'", that 'gsap' is pointing to TweenMax which is why that's what's being loaded. From what I can tell, everything is working as it should. Is there a reason you don't want TweenMax to load? 

 

And for the record, this applies to version 1.19.0 (ES6 import statements probably wouldn't work with earlier versions)

Link to comment
Share on other sites

Just tested, and the imports work, but as you mention, it imports a lot of other unneeded stuff with the current setup. I get TimelineMax imported (because it's in TweenMax.js), which unnecessarily bloats my build file. I'm using JSPM 0.17 beta for reference. Will try the direct path ref to avoid these extra imports. 

Link to comment
Share on other sites

Looks like it's partly working, I can do this:

import TimelineMax from 'gsap/TimelineMax';

And with JSPM it will import Tweenlite.js also, but looks like TimelineMax doesn't define TweenMax as a dependency - should it do that?

 

Simple things like this work (except for the yoyo and repeat part): 

        var timeline = new TimelineMax();

        var valueProxy = {
            x: 0
        };

        timeline.to(valueProxy, 1, {x: 100});
        timeline.to(valueProxy, 1, {x: 0, yoyo: true, repeat: -1, onUpdate: ()=> {
            console.log(valueProxy.x);
        }});

but this doesn't:
 

        var timeline = new TimelineMax();

        timeline.to(document.body, 1, {backgroundColor: '#ff2080'});
        timeline.to(document.body, 1, {backgroundColor: '#000000', yoyo: true, repeat: -1});
Link to comment
Share on other sites

Yep, that's **exactly** how it is supposed to work. That way, you can keep file size down if you don't need the extra features in TweenMax. But if you load it, you'll kinda "unlock" those repeat/yoyo/repeatDelay features in tweens. Keep in mind that TimelineMax has repeat/yoyo/repeatDelay features itself (on TimelineMax instances, not tweens that you insert), so you can use that to your benefit if you'd like. 

Link to comment
Share on other sites

Okay, with the risk of having missed something (again :-D) I have a question:
If I only import TimelineMax from TimelineMax.js, this code won't work:

        var timeline = new TimelineMax();

        timeline.to(document.body, 1, {backgroundColor: '#ff2080'});
        timeline.to(document.body, 1, {backgroundColor: '#000000', yoyo: true, repeat: -1});

However if I also import TweenMax from TweenMax.js it now works. The thing is though, that it also works, if I only import {TweenMax, TimelineMax} from TweenMax.js - so isn't the code for TimelineMax duplicated into TweenMax.js, does doubling the code payload to include it? 

Essentially making it impossible to optimize the amount of code you import to only TweenMax and TimelineMax?

Link to comment
Share on other sites

HI supermoos,

 

The issue is that you're not including the CSS Plugin as well.

 

In a previous post you included this snippet;
 

var timeline = new TimelineMax();

var valueProxy = {x: 0};

timeline.to(valueProxy, 1, {x: 100});
timeline.to(valueProxy, 1, {x: 0, yoyo: true, repeat: -1, onUpdate: ()=> {
  console.log(valueProxy.x);
}});

Since you're using just an object, the core of the engine updates the value as expected. But in your latest snippet you're telling GSAP to animate CSS properties, which without the CSS Plugin can't be done. You should include the CSS Plugin

import CSSPlugin from 'gsap/plugins/CSSPlugin';

If that's the route you have in your modules to the CSS Plugin.

  • Like 1
Link to comment
Share on other sites

I see the confusion.

 

The thing is that the TweenMax file includes, by design, the following:

 

TweenLite, TweenMax, TimelineLite, TimelineMax, CSS Plugin, Ease Pack, Bezier Plugin, Directional Rotation Plugin, RoundProps Plugin and the AttrPlugin.

 

There has been in the past questions and requests regarding this issue and, to be completely honest with you, I'll be in favor of a way of creating your own bundle (like jQuery does with the NPM package) so one can choose what to include for specific case use. But again the TweenMax.min file is just 33~ KB compressed and being objective that's not too much weight.

 

Also it is worth noticing that the code of the TweenMax file is open source, so you can change it if you wish, but at that stage you're on your own. The forums are intended to provide support for the files provided by the download, NPM package, Bower and Git repository download/fork. We can't support issues derived from users changing the core files. Hopefully you understand that is not because we don't want to help users. This community is, and I know I speak for the Carl, Jack, the moderation team and other users that go the extra mile to give support, all about helping the users and going the extra mile while we're at it, but for time limitations we need to draw a proverbial line at some point.

 

I invite you to keep discussing this and any other concerns and ideas you might have and I can assure you, that you'll always find a good willing answer.

 

Happy Tweening!!

  • Like 3
Link to comment
Share on other sites

Sorry about any confusion there, but we actually put a lot of thought into how we packaged things - it's very much by design. Let me explain...

 

Actually, it might help if you first read this: http://greensock.com/kilobyte-conundrum/

 

If we allow people to build custom variants:

  1. It ruins the caching benefit. If, on the other hand, there's a standard "TweenMax" file that has ALL of the most commonly used pieces (which of course includes the timeline classes), it allows everyone to benefit from ubiquitous caching, meaning that in most cases the file size cost is literally ZERO. So [counter-intuitively] this way of packaging is actually better for those worried about file size. Remember, every major ad network has GSAP on their CDN and due to its ubiquity, they all whitelist it from file size calculations. That's a TREMENDOUS benefit for ad designers/developers who need to obsess about file size. 
  2. It would likely cause problems with mis-matched feature sets in the wild. Let's say one site has a "TweenMax" without any timeline classes or CSSPlugin, but then they drop some content into the site from another developer who wrote code that depends on the timeline classes or CSSPlugin being activated in TweenMax. Oops. Stuff breaks. Then we get questions/complaints in the forums about TweenMax not working. See the problem? It could just turn into a support nightmare and be confusing for end users.
  3. It won't really deliver that much of a performance gain (not worth all the hassle). In the real world, the file size difference between loading the "regular" TweenMax and some custom slimmed-down version that only has certain pieces might load less than 1 second faster (probably not even noticeable). And it has capabilities ripped out. 

I've thought a lot about this whole file size issue - over the years, it has been a major focus of mine especially because GSAP is so widely used in ads which must be as compact as possible. But I've really tried to step back and look at the bigger picture, especially in light of overall performance. For example, I've made some choices code-wise that prioritize runtime performance over file size because frankly I think it's much more important for an animation engine to be as fast as possible at runtime even if it takes 0.03 seconds longer to load. Animation is probably the most performance-sensitive part of UX. But it's always a balancing act between writing FAST code and writing SMALL code and engineering the whole system to be exceedingly robust and flexible. Yes, I want all 3, but in today's world I firmly believe that it's better to prioritize runtime performance and being robust (to allow animators to accomplish almost anything animation-wise with minimal code) rather than myopically focusing on the smallest file size (although there are limits of course - I wouldn't want GSAP to be 200kb). 

 

For example, there's a new-ish animation engine that made a marketing push in the last few weeks that makes a big deal about claiming to be about 9kb. That's great, and I congratulate them...but it's significantly slower than GSAP. I dropped it into my speed test and...wow. It literally crashed the browser it was so slow under pressure. GSAP was at least 20x faster. And of course GSAP can do much, much more (features-wise). Some animators don't really think about all the tradeoffs and they get stuck on the file size issue; after all, 9kb sounds so much better than 33kb. But when you look beyond that you might start to see how dangerous that trade is. Then again, if you're not doing much animation (don't need to care much about performance) and you don't need the features or ongoing maintenance/support GSAP offers, perhaps it is wiser to just use that smaller engine because it loads faster (well, not faster than a cached TweenMax, but... :) )

 

And yes, the timeline classes are supposed to be inside of TweenMax because I consider them pretty essential. TweenMax is intended to be the "load one file and I get pretty much everything I need", yet for those who are hyper concerned about file size we do provide TweenLite and the various other tools to be loaded independently.

 

Again, please read that article I mentioned above, chew on why we've made the decisions that we have, and let me know if you've got other suggestions. 

 

Good discussion. Glad you asked. 

  • Like 4
Link to comment
Share on other sites

Hi Jack and Rodrigo

Thanks for your lengthy reply, nice to see how much effort you put into support! 

 

In regards to 1:
I definitely undestand your thoughts about TweenMax from an ad developers perspective. I'm however not developing ads, and don't benefit from the caching since we bundle most of our source code up.

2. point:
This one I see as a problem, I remember this problem from the flash days of using greensock, not getting why something wasn't tweening, just to realize I had forgotten to import (or activate) the right plugin. However, this is something you rather quickly learn after having hit this problem a few times. And could potentially be solved by having console.log's for tweening values that are in an un-included plugin. These console.log's should not be in the minified / production code. I don't know if this would have to much of a performance impact / bloat the code even more, but maybe it could be in a debug-plugin?

And yeah, definitely keep prioritizing performance, ease-of-animation over pure kb's - gsap is amazing, and I agree that the 33kb subjectively isn't a lot, but I was basically just trying to optimize my build, so that importing TimelineMax might have TweenMax as it's dependency. Then it would be auto-imported (along with TweenMax's dependencies, CSSPlugin etc.). This should be possible with ES6 modules.

Link to comment
Share on other sites

To clarify, I didn't mean to imply that the caching benefit is limited to banner ad developers. There are tons of sites linking to our CDNJS files, thus you can just point at those and tap into the caching benefit immediately. If you prefer to just include all the JS in your own payload, that's totally fine too (but as you indicated, you wouldn't get the caching benefits, that's all). 

 

Yes, the "oh shoot, I forgot to load that plugin" thing is something people just need to learn. But even back in the Flash version, we automatically activated a bunch of common plugins in TweenMax because it was geared to be the robust, "plop it in and forget it" option. Sure, we could require people to manually load each of those common plugins instead, but:

  1. You'd be surprised how many people struggle with that. We want to reduce friction for developers. Think of TweenMax almost like a Lexus car that has a bunch of plush features and conveniences built in. A sports car racing enthusiast might turn up his nose and insist that if they removed the fancy big-screen GPS, sunroof, TV screens behind the headrests, and swapped out the plush suspension for a stripped-down sporty rendition, they'd shave off several hundred pounds and make it faster. But the typical Lexus customer doesn't care about that - they'd much rather have the conveniences. Likewise, TweenMax isn't aimed at people who are obsessing about file size (TweenLite is for that). 
  2. You might actually end up with WORSE loading performance due to latency. Loading one 33kb file is typically much faster than loading 8 files that add up to 28kb. Then again, I realize that you are planning to squish them all into a single JS file during your build process, so that negates this point in your particular case, but there are plenty of folks out there who want to load TweenMax over a CDN link and this "rip out all the plugins and make them load them manually" would affect them. 

Anyway, we do plan to move to ES6, so some of those will be moot at that point (though we still plan to have a compiled TweenMax.js file that has a similar bundle of common plugins and timeline classes, even after we move to ES6).

 

Thanks for the discussion and suggestions!

  • Like 1
Link to comment
Share on other sites

Anyway, we do plan to move to ES6, so some of those will be moot at that point (though we still plan to have a compiled TweenMax.js file that has a similar bundle of common plugins and timeline classes, even after we move to ES6).

 

 

Seems like a fantastic plan :-) And thank you for taking the time to discuss this matter! 

  • Like 2
Link to comment
Share on other sites

Sorry for hijacking this thread, but I've been unsuccessfully trying to import the Draggable utility in my Webpack project like this, thinking the syntax would be the same as it is for the plugins:

import Draggable from 'gsap/utils/draggable'

Which leads to Module not found: Error: Cannot resolve module 'gsap/utils/draggable'.

 

What's the correct way to go about this?

  • Like 1
Link to comment
Share on other sites

@fraenzn 

 

I'm not to familiar with Webpack, but I had the similar issue with browserify.

there are couple of web pack specific threads that may help:

 

http://greensock.com/forums/topic/13478-draggable-on-aurelia/#entry56286

http://greensock.com/forums/topic/10464-how-to-access-plugins-and-utils-through-npm-module/#entry63422

 

I was able to get Draggable to in work Browserify by adding :

"browser": {
   "Draggable": "./node_modules/gsap/src/uncompressed/utils/Draggable.js"
 },

then just requiring it like:

require ("Draggable");

Based on one of the above threads, it seems you can add the following to your webpack config file: (maybe..?.. not webpack expert)


resolve: {
  root: path.resolve(__dirname),
  extensions: ['', '.js'],
  alias: {
    "Draggable": "path_to_Draggable"
    
  } 

}

  • Like 2
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.
×
×
  • Create New...