Jump to content
Search Community

Webpack issue with *club greensock* plugins

ad_bel 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

Hi,

 

I know webpack has been talked about extensively here but all the solutions I have found involve the same publicly available modules.

 

I am doing something like this (I use vbuild so the syntax is different): https://github.com/OSUblake/gsap-webpack/blob/master/gsap-webpack/gsap-webpack/webpack.config.js

 

...where I have an alias for Tweenlite the same way as above.

 

When I go to import private (club membership) modules I can sucessfully import CustomEase from easing as well as SplitText from the utils folder but I cannot import MorphSVGPlugin or ThrowPropsPlugin from the plugins folder??? If I debug the module value:

 

//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date)
(function(name) {
"use strict";

console.log(module); //module.exports -> undefined

var getGlobal = function() {
return (_gsScope.GreenSockGlobals || _gsScope)[name];
};

if (typeof(define) === "function" && define.amd) { //AMD

define(["TweenLite"], getGlobal);
} else if (typeof(module) !== "undefined" && module.exports) { //node

require("TweenLite");
module.exports = getGlobal();
}
}("ThrowPropsPlugin"));

 

the module.exports value is undefined (it is not in the CustomEase or SplitText components for example).

 

I am importing like this (note: there is an index.js file in the easing and plugin folders that export those modules):

 

import { CustomEase } from 'src/vendor/gsap/easing';
console.log(CustomEase);

import ThrowPropsPlugin from 'src/vendor/gsap/plugins';
console.log(ThrowPropsPlugin);

 

CustomEase imports perfectly fine while ThrowPropsPlugin does not (because module.exports is undefined from above).

 

I am not sure how to get these plugins to work... Anyone have any ideas???

 

Thanks!

Link to comment
Share on other sites

It depends which files you dropped in there. The members-only zip contains a "bonus-files-for-npm-users" folder with files that are built for a flat folder structure (to make it easy). And it also has the bonus stuff in the more nested structure inside the "uncompressed" and "minified" folders. So it's totally up to you and what you prefer. It sounds like maybe you tossed the flat ones into the nested structure? Tough to say without seeing your setup. 

 

Does that help at all? 

Link to comment
Share on other sites

Hi Jack,

 

Nope. I am using the uncompressed one (so I can have source in dev if needed) and just let webpack compress it when i build it.

 

My structure is as follows:

 

package.json

 

"dependencies": {

...
"gsap": "^1.19.1",

...
}

 

I get the public modules from npm and just add the club ones (1.19.1) I need like this in my project:

 

vendor/gsap/easing

 

CustomEase.js

index.js

 

vendor/gsap/plugins

 

MorphSVGPlugin.js (VERSION: 0.8.8)

ThrowPropsPlugin.js  (VERSION: 0.11.0)

index.js

 

vendor/gsap/utils

 

SplitText.js

index.js

 

 

...where index.js looks like this for example:

 

import CustomEase from './CustomEase.js';

console.log(CustomEase); // <---- This is undefined (see my original post to see the module.exports in the actual component is undefined) 

export { CustomEase }

export default {
CustomEase
}

 

Also note in the plugins I changed the following:

 

//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date)
(function(name) {
"use strict";
var getGlobal = function() {
return (_gsScope.GreenSockGlobals || _gsScope)[name];
};

if (typeof(define) === "function" && define.amd) { //AMD
define(["TweenLite"], getGlobal);
} else if (typeof(module) !== "undefined" && module.exports) { //node

require("TweenLite"); // <--- ***** Changed this for all since I have it aliased in Webpack. Was looking for a specific path but I get it from npm ****

module.exports = getGlobal();
}
}("CustomEase"));

 

 

My webpack config looks like this (note: I am using vbuild - https://vbuild.js.org so the syntax is different but its still just webpack2):

 

const path = require('path');
const OfflinePlugin = require('offline-plugin');
const webpack = require('webpack');

module.exports = options => ({
entry: 'src/index.js',
html: {
template: './src/index.ejs'
},
webpack(config) {

// inject offline-plugin in production build
if (!options.dev) {
config.plugins.push(new OfflinePlugin({
ServiceWorker: {
events: true
}
}))
}

config.plugins.push(new webpack.ProvidePlugin({
TweenLite: "gsap"
}));

var gsapVendor = './src/vendor/gsap';

config.resolve.alias.TweenLite = 'gsap';

 

//Tried aliasing as well but didn't make a difference
// config.resolve.alias.CustomEase = path.resolve(gsapVendor + '/easing/CustomEase.js');
// config.resolve.alias.MorphSVGPlugin = path.resolve(gsapVendor + '/plugins/MorphSVGPlugin.js');
// config.resolve.alias.ThrowPropsPlugin = path.resolve(gsapVendor + '/plugins/ThrowPropsPlugin.js');

console.log(config);

return config
}
});

 

Finally inside my component I do the following:

 

import { TimelineMax, TweenMax } from 'gsap';

console.log(TimelineMax); // <---- Good
console.log(TweenMax); // <---- Good

import CustomEase from 'src/vendor/gsap/easing';
console.log(CustomEase); // <---- Good

import { SplitText } from 'src/vendor/gsap/utils';
console.log(SplitText); // <---- Good

import MorphSVGPlugin from 'MorphSVGPlugin';
console.log(MorphSVGPlugin); // <---- Undefined

import ThrowPropsPlugin from 'src/vendor/gsap/plugins';
console.log(ThrowPropsPlugin); // <---- Undefined

 

 

That's pretty much all I am doing :/ Any other ideas?

Link to comment
Share on other sites

Also removed the npm install of gsap and just tried using *flat structure* (without webpack alias) in my project and imported in my component like this:

 

import CustomEase from 'src/vendor/gsap/CustomEase';

 

and it gives me an empty object (none of the modules work) :/

Link to comment
Share on other sites

To be clear, the stuff in "commonjs-flat" is indeed uncompressed, so you don't need to feel like you've gotta use the files from /uncompressed/ if that's you're concern.

 

I'm no Webpack expert so it's kinda tough to troubleshoot your particular project but I know that plenty of people are using GSAP in Webpack without a problem. Sounds like some odd path issue. 

 

This struck me as very odd: 

import { SplitText } from 'src/vendor/gsap/utils';

Isn't it supposed to point to a file, not a directory? Like "gsap/SplitText"? Have you tried the simple "gsap/[CLASS]" syntax? 

Link to comment
Share on other sites

  • 1 month later...

having trouble with CustomEase in webpack as well. if i'm installing gsap through npm, then i need to have the special plugins in the projects own source, and in the case with CustomEase its throwing an error that CustomEase cannot resolve module TweenLite. if someone has a license to use the special case gsap plugins, they're still gonna want to install the majority of gsap through npm.

Link to comment
Share on other sites

You can install all the special plugins through npm...

https://stackoverflow.com/questions/10386310/how-to-install-a-private-npm-module-without-my-own-registry

 

It can be as simple as a local folder. 

 

y6W3FAJ.jpg

 

Create a package.json for it.

{
  "name": "gsap",
  "version": "1.19.1",
  "main": "./TweenMax.js"
}

 

Now you can import like this with Babel.

import { TweenMax } from 'gsap'
import CustomEase from 'gsap/CustomEase'

 

With TypeScript.

import { TweenMax } from 'gsap'
import * as CustomEase from 'gsap/CustomEase'

// or
import CustomEase = require('gsap/CustomEase')

 

Or skip the naming stuff altogether as GSAP is global.

import 'gsap'
import 'gsap/CustomEase'

 

  • Like 3
Link to comment
Share on other sites

  • 2 months later...

@OSUblake How do you keep that folder up to date? I don't know if this is possible but wouldn't it make more sense to create that folder just for the Custom Plugins and not for the whole Greensock Library?

 

So you could do something like 

import { TweenMax } from 'gsap';
import CustomEase from 'mygsap/CustomEase';

 

Now the Core Library will be up to date because it is still managed by npm and the CustomPlugins need to updated by hand anyway.

  • Like 1
Link to comment
Share on other sites

Yes, you can do it like that. But keep in mind that the core files and plugins are updated and released together. Don't assume that an older version of the plugin will work correctly with a newer version of a core file or vice versa.

 

To keep that folder up to date, you're going to have to check yourself, or write a script to check for you. But you can convert that folder into a git repo. That will give you version control, allowing you to install different versions of GSAP. That's the main reason I linked to that Stackoverflow question. It wasn't to show how to use a local folder.

Link to comment
Share on other sites

Just to be clear, it's EXTREMELY uncommon for an older version of a plugin to be incompatible with a newer version of the core. We take backwards compatibility very seriously and I can't remember the last time there's been a plugin that'd be incompatible with any version of GSAP. The exception, of course, would be a major version bump (which has never happened for the JS version of GSAP, but it will happen at some point in the future).

 

So in general, you really don't have to worry about trying to keep the plugins on the same update cycle as the core files. Of course I'd always recommend using the latest of everything, but you don't generally need to worry about slightly outdated bonus files (at least in terms of compatibility with the core). 

  • Like 1
Link to comment
Share on other sites

Wow lot's of traffic to this post all of a sudden ;)

 

Part of the the problem here is that we are used to keeping our packages up to date via npm update. This is especially true when doing continuous deployment and automated builds while working in larger teams (as @danehansen mentioned). This works great until we hit the paid libraries for obvious reasons.

 

@GreenSock I agree with @OSUblake that you you want to upgrade everything at once. Updating only portions of libraries (no matter how hard you try) can lead to hard to fix intermittent bugs. 

 

@OSUblake - Sure you can install from your own git repo but that still means that you have to keep that up to date manually. That is much more work then doing: "npm update gsap" which is all we should have to do. Now in reality, gsap really doesn't change that often (unlike many other libraries) so it is doable but not ideal.

 

I think a better way is for *Greensock* to setup a private repo for paid members that provides them with a username/password that they receive  their subscription. This way paid members update *everything* from this private repo and non paying members just update via the public repo. Also *your* deployment is now only in only 2 places vs distributing files and having to help people debug when things inevitably go wrong or people can't get it to work ;)

 

I know you guys focus more on the actual greensock product suite (as you should) but the reality is we need a better packaging system here. I understand you can't support every option out there but Webpack is pretty much the defacto standard and integration should be supported

 

  • Like 2
Link to comment
Share on other sites

Right, that's the issue - it wouldn't solve anything to have a private repo that we send the username/password out to all club members because:

  • What happens when the person's membership expires? How could we make sure that only active members have access?
  • How would we prevent someone from just sharing that username/password broadly and then everybody gets access for free? 
  • Wouldn't it be even more of a pain if we had to keep changing the username/password to keep things secure, and then every club member has to keep manually updating their credentials? 

The way things work now seems to be completely compatible with webpack - I'm struggling to see how or why it's so terrible if once in a while folks [optionally] log into their account and grab the latest files, especially because they're almost always backwards-compatible and don't get updated that frequently anyway (the members-only plugins). 

 

If anyone finds a good solution for the subscription-based repo stuff, please do share. 

Link to comment
Share on other sites

@Greensock - because we all have had major problems getting this to work with webpack. In fact I originally posted this problem and I still never got this to work in my environment so I gave up and used the free plugins. I have been a paying customer for over 3 years and I do not use your paid plugins (so basically I pay for nothing other than to support you guys :) ) not because they aren't good or I don't want to but because it is 1 million times more important for me to have webpack than this library.

 

I build business apps and I use greensock for UX but I cannot build these apps without webpack due to the complexity. You were saying why not grab the files every once in awhile... well I can't work if I have to do this for my 1000's of dependencies (project I'm looking on right now has 2,981 lol). Then add in CI/CD, automation etc... that we use in the corporate development world and it is hard enough to manage.

 

I mean I get it that your perspective is probably different from us but judging by the comments there are others here that are struggling with this as well ;)

 

As far as your concerns:

 

1. When a membership expires permissions should be provoked. Whatever solution you use should have this baked in or its useless

2. Access and giving out passwords... well someone can drop your files in dropbox or email them around now. I don't see how this makes it any less secure.

3. I don't understand your last point? Are you referering to a common u/p? No don't do that lol.... any subscription based software should have that baked in (see point #1)

 

I think this is worth doing some research on. I have never had a need for this so haven't ever looked into but maybe someone else here has?

 

*Note to self* make sure you unsubscribe to posts otherwise you get sucked back into conversations! lol

  • Like 2
Link to comment
Share on other sites

59 minutes ago, ad_bel said:

*Note to self* make sure you unsubscribe to posts otherwise you get sucked back into conversations! lol

 

Don't do that! Your feedback is good. :-D

 

I think most of the stuff to make this work is already implemented. How do you download the member plugins? Well, there's a url that looks something like this.

https://greensock.com/forums/files/file/5-gsap-with-business-green-bonus/?do=download&csrfKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

And npm can install from a url. So it seems like the only thing missing here is a way to authenticate that key or a token without using your browser. 

 

Link to comment
Share on other sites

i suppose i will jump back in here too. i wanted to include some other reasons to move to a traditional build system (doesn't HAVE to be webpack, but might as well be webpack)

1. collaboration/forking - i know you guys dont accept PRs because you maintain the code yourself, but having a more traditional build can allow people to help try stuff out, which you could in turn decide whether or not you want to incorporate. also could allow users/businesses to fork the repo and use their own flavor. currently the git repo and what is installed from npm appear to be unrelated so it is quite difficult to be able to alter the gsap code and have it installed via npm.

2. ability to more easily get away from the global scope. its unavoidable for users installing via script tags, but for those using npm, it is sometimes quite important to keep the global scope clean. it can become a security issue. the duality of globals for script tag importers and privates for npm users can be solved with UMD, built into webpack.

3. your source code will be simplified and easier to understand if you let webpack handle the dependencies rather than various other hacks.

4. the longer these difficulties exist, the more open to the danger of a major tech company (google, facebook, etc...) putting an entire team of engineers on the task of creating an open source/free animation library that would almost certainly be immediately adopted throughout the tech community, and in turn be adopted by casual users. if your library is easy for everyone to implement and doesn't make anyone have to compromise, no one will want to re-solve the problem.

5. javascript changes so fast, and its always good to keep up with latest common practices for your own knowledge/experience.

  • Like 1
Link to comment
Share on other sites

@danehansen excellent points! This is a fantastic library but for it to remain relevant it must adapt as technologies change

 

@OSUblake that's a good start. As long as you have it use npm you also get warnings for dependencies issues etc... you might want to start with github submodules to the public gasp library. This way you update the core stuff in that library and it's automatically included in the full library. This would help with not having to have two code bases to maintain as well as keeping all git history.

 

Ultimately you would want to put a package.json with a dependency to the gasp library. Only reason you may not do it right away is because all your link dependencies will change. Not sure how big of a task that is but if it's not I think that's a better approach :)

 

as for the token/permissions I'm not sure. That would require some research. I have never done anything like that :/

  • Like 1
Link to comment
Share on other sites

Thanks for the input, guys. 

 

@ad_bel thanks for being a paying customer even though you weren't using the bonus plugins! That means so much to us. Seriously, people like you empower what we do around here. My hat's off to you, kind sir. 

 

@danehansen I know you've also been a big supporter historically. And of course @OSUblake, you're a MASSIVE contributor around the community here, and I'm eternally grateful for what you do. 

 

---

 

For the record, the NPM code is identical to the github code except that we also add a copy of all stuff in the root (with dependencies adjusted accordingly) to make it simpler to import. 

 

I'll certainly be exploring how to more closely wire GSAP up to a build system; I'm just cautious at this point because: 

  1. I've heard there are performance tradeoffs, and that may be a deal-breaker. It's gonna take some time to really dig into that and ensure that we're not just jumping on the latest cool trend (webpack/babel these days) because everyone says it's what people are "supposed" to do. Not that anyone is advocating that here, of course. I'm just saying that when it comes to an animation library, it's a very different ballgame than typical apps that most people are used to tackling with the workflow being prescribed in the broader JS community. We've gotta be super careful about performance as well as broad browser compatibility (most ad networks lean on GSAP heavily). 
  2. We've been heads-down on some other features that we wanted to push out before the major 2.0.0 rewrite. Plus there have been some unexpected site-related challenges that have taken a lot more time than anticipated (I won't bore you with the details...super frustrating). We also completely rebuilt the tech stack that drives the docs (they're now largely static files and can even be downloaded). So we've been focused elsewhere, but I'm very eager to get past it and dig more into a 2.0.0 rewrite. Lots of ideas have been bubbling. 
  3. Frankly I'm a bit discouraged by how much of a moving target these things are, and I generally like to see things settle down a bit before committing. A while ago, Browserify was touted as the best, now it's Webpack, Bower seemed big...and then it wasn't, there's Grunt/Gulp, React/Vue, ES6/Babel, etc., etc. If we went all-in on Browserify and Bower, we might be stuck doing a lot of rewriting when things shifted more to Webpack. I realize, though, that at some point ya gotta just jump in, choose something and hope for the best. We're close to doing that now, so again, thanks for the input. 

As for some big company swooping in and building a competing engine that makes GSAP obsolete, you very well could be right but I don't like operating out of fear like that. I prefer to focus on doing our best to serve the community and trust that if we keep doing that well, there's nothing to worry about. We've got an amazing group of supporters and talented users, and we love building stuff that'll make them happy. Will we do it all perfectly? Nope. I wish I could iterate things faster and have a wonderful solution for your "bonus plugins in NPM/Webpack" question. I wish a lot of things, but nevertheless, we'll keep on getting up day after day and doing our best to crank out (and support) solid solutions that help developers and designers solve animation-related problems. It's what we love doing; we consider it a privilege. 

 

Thanks for your patience, support, and suggestions. We're listening. 

  • 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...