Closed tonix-tuft closed 4 years ago
Hm, well from your sample code above it looks like you are animating things that'd require CSSPlugin (like transforms and opacity...I assume that's CSS-related, right?)
But advanced users could get around the CSSPlugin auto-activation by only importing directly from gsap-core instead of the typical "gsap". Of course that means that any CSS-related animations won't work.
Does that answer your question?
Thank you for your reply @jackdoyle!
Hm, well from your sample code above it looks like you are animating things that'd require CSSPlugin (like transforms and opacity...I assume that's CSS-related, right?)
Yes, that's CSS-related stuff as well as very simple animations. The thing is, all this functionality is not used by pigretto
, which is a proxy library, but CSSPlugin
and gsap-core
ends up being bundled in the final pigretto
build (transform()
, fadeIn()
, fadeOut()
don't), because gsap
's code prevents it to be tree-shaked.
I tried to do the following:
// I created an extra file called js-utl/src/externals/gsap.js
// with the following content:
import { gsap } from "gsap/gsap-core";
import { CSSPlugin } from "gsap/CSSPlugin";
/**
* @type {boolean}
*/
let registered = false;
/**
* @type {null|gsap}
*/
let GSAP = null;
export default function getGSAP() {
if (!registered) {
registered = true;
gsap.registerPlugin(CSSPlugin);
GSAP = gsap;
}
return GSAP;
}
Then, in animation.js
:
...
/**
* Animation utility functions.
*/
import { millisecToSec } from "./time";
import getGSAP from "../externals/gsap";
...
export function fadeIn(node, options) {
const opt = options || {};
const secs = millisecToSec(opt.millisec || 300);
const css = opt.css || {};
const gsap = getGSAP();
gsap.fromTo(
node,
secs,
{
opacity: 0,
display: css.display || "block",
...(opt.fromCSS || {})
},
{
opacity: 1,
...(opt.toCSS || {}),
onComplete: () => {
opt.onComplete && opt.onComplete();
}
}
);
}
...
export function fadeOut(node, options) {
const opt = options || {};
const secs = millisecToSec(opt.millisec || 300);
const css = opt.css || {};
const gsap = getGSAP();
gsap.fromTo(
node,
secs,
{
opacity: 1,
display: css.display || "block",
...(opt.fromCSS || {})
},
{
opacity: 0,
...(opt.toCSS || {}),
onComplete: () => {
gsap.set(node, {
display: css.displayOnComplete || "none"
});
opt.onComplete && opt.onComplete();
}
}
);
}
And in css-in-js.js
:
...
/**
* CSS-in-JS utility functions.
*/
import { prefix } from "inline-style-prefixer";
import { cssifyObject, resolveArrayValue } from "css-in-js-utils";
import { isArray } from "./core";
import getGSAP from "../externals/gsap";
...
export function transform(element, ...transforms) {
const gsap = getGSAP();
gsap.set(element, Object.assign({}, ...transforms));
}
But even this way, pigretto
using js-utl
ends up with CSSPlugin
as well as gsap/gsap-core
being bundled even though it doesn't use any of the animation.js
and css-in-js.js
functions exported by js-utl
(which in turn import gsap
).
But advanced users could get around the CSSPlugin auto-activation by only importing directly from gsap-core instead of the typical "gsap". Of course that means that any CSS-related animations won't work.
If I do not import from gsap/CSSPlugin
, but import from gsap/gsap-core
only, will import { gsap } from "gsap/gsap-core"
include tree-shakable code?
Could you make a snippet of an example where you import gsap/CSSPlugin
as well as gsap/gsap-core
so that both are tree-shakeable (if it's possible, of course)?
Meanwhile, the alternative solution for me was to split animation.js
and css-in-js.js
into a new dedicated NPM package requiring gsap
as a dependency called gospel
, and release a major 4.0.0 version of js-utl
without those files using gsap
.
This way I was able to cut pigretto
's final minified bundle size by a factor of ~2 (from ~113 KiB down to ~48.9 KiB).
The new gospel
package has a minified build of about ~60 KiB and bundles gsap
's core and its CSSPlugin
.
What is the size of gsap
's core together with CSSPlugin
when minified? About ~50 KiB, I guess.
Thank you!
Could you make a snippet of an example where you import gsap/CSSPlugin as well as gsap/gsap-core so that both are tree-shakeable (if it's possible, of course)?
If you don't use an import, it will be dropped. You are using both in this snippet.
// I created an extra file called js-utl/src/externals/gsap.js
// with the following content:
import { gsap } from "gsap/gsap-core";
import { CSSPlugin } from "gsap/CSSPlugin";
/**
* @type {boolean}
*/
let registered = false;
/**
* @type {null|gsap}
*/
let GSAP = null;
export default function getGSAP() {
if (!registered) {
registered = true;
gsap.registerPlugin(CSSPlugin);
GSAP = gsap;
}
return GSAP;
}
Imports aren't conditional. If you need a conditional import, then you have to use dynamic imports. Something like this.
import('/node_modules/gsap/index.js')
.then((module) => {
// Do something with the module.
});
@OSUblake Yes, I am using both, but this snippet was a file called js-utl/src/externals/gsap.js
and its getGSAP()
function was only imported and used within js-utl/src/modules/animation.js
and js-utl/src/modules/css-in-js.js
.
On the other hand, pigretto
doesn't use getGSAP()
and any of the fadeIn()
, fadeOut()
and transform()
functions exported by js-utl/src/modules/animation.js
or js-utl/src/modules/css-in-js.js
.
Indeed, those functions of js-utl
do not end up in the pigretto
's build, but CSSPlugin
and gsap-core
does (which doesn't make sense), that's why I was looking for a way to tree shake gsap
's code away from pigretto
's build... as it's not required by pigretto
.
I don't know how or if tree shaking is so supposed to work for stuff imported in another package. Tree shaking isn't a standard, and it's up to the build tool to decide how it works. You said you were using webpack, but have you tried using rollup?
Didn't try with rollup
, I use Webpack
to bundle most of my JS libraries. I use rollup
for React libraries though, so maybe I can give it a try in the future!
Thank you, anyway.
I am closing this as I ended up moving all the code requiring gsap
in a dedicated package.
Hello,
I am using
gsap
in some modules related to CSS stuff and animations in a utility library calledjs-utl
(https://github.com/tonix-tuft/js-utl). Some of the functions requiringgsap
are:./js-utl/src/modules/css-in-js.js
./js-utl/src/modules/animations.js
I then use this
js-utl
library as a dependency of my other libraries, e.g.pigretto
has a dependency onjs-utl
(https://github.com/tonix-tuft/pigretto).However,
pigretto
only uses three functions exported byjs-utl
(namelyisArray
,isUndefined
andisEmpty
) and none of them have anything to do withgsap
(pigretto
is not a CSS/animation lib but only uses some functionality ofjs-utl
which does not requiregsap
).Then, when I generate the Webpack
production
build ofpigretto
, tree shaking works as expected for the three functionsisArray
,isUndefined
andisEmpty
, which are the only functions exported byjs-utl
that get bundled (I have double-checked it and e.g.ctypeDigit
of./js-utl/src/modules/core.js
does not get bundled as it is not used bypigretto
, as well astransform
andfadeIn
).CSSPlugin
, however, is bundled together withpigretto
's code, though I wouldn't expect it to be.That's, as far as I understand, because you implicitly register the plugin in your
gsap/index.js
file:Is there a way to tweak tree shaking even in this case and avoid including
CSSPlugin
andgsap-core
at all if the client code (in my casepigretto
) usingjs-utl
doesn't use the functions exported byjs-utl
which requiregsap
liketransform
and/orfadeIn
?Thank you for the attention and for this library.