I have a utility library: goodcore That I am using in another project. It works fine but when I use Rollup to bundle and treeshake it, it always includes the whole goodcore library, even when I only use a very small portion of it that have no links what so ever to some of the included files.
Both projects are Typescript and use ES2015 module loading.
I reference the goodcore library using:
import { Arr, Pool, Range2, Timer, Util, Vec2 } from "goodcore";
and the index.js in goodcore looks like:
export { Vec2 as Vec2 } from "./struct/Vec2";
export { Range2 as Range2 } from "./struct/Range2";
export { Rect as Rect } from "./struct/Rect";
export { List as List } from "./struct/List";
export { Dictionary as Dictionary } from "./struct/Dictionary";
export { Stack as Stack } from "./struct/Stack";
export { Tree as Tree } from "./struct/Tree";
export { Calc as Calc } from "./Calc";
export { Dom as Dom } from "./Dom";
export { Arr as Arr } from "./Arr";
export { Obj as Obj } from "./Obj";
export { Util as Util } from "./Util";
export { Timer as Timer } from "./Timer";
export { Uri as Uri } from "./Uri";
export { Poolable as Poolable } from "./standard/mixins/Poolable";
export { Initable as Initable } from "./standard/mixins/Initable";
export { Pool as Pool } from "./standard/Pool";
export { Integrate as Integrate } from "./Integration";
export { MocData as MocData } from "./MocData";
export { Cache as Cache } from "./standard/Cache";
export { KeyValuePair as KeyValuePair } from "./struct/KeyValuePair";
//# sourceMappingURL=index.js.map
Still I end up with everything from goodcore, like the Tree, included in my rollup build of the other project, while I was under the impression that the treeshaking should remove things that were not used/referenced.
The rollup config for the other project looks like this:
var packageJson = require("./package.json");
import resolve from 'rollup-plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';
export default {
entry: 'src/lib/index.ts',
targets: [
{ dest: 'dist/' + packageJson.name + '.umd.js', format: 'umd' },
{ dest: 'dist/' + packageJson.name + '.es.js', format: 'es' },
{ dest: 'dist/' + packageJson.name + '.iife.js', format: 'iife' }
],
moduleName: packageJson.name,
external: ['ts-md5/dist/md5'],
sourceMap: true,
globals: {
},
treeshake: true,
plugins: [
typescript({
typescript: require('typescript')
}),
resolve({ module: true, jsnext: false, main: true, modulesOnly: true })
]
}
What am I doing wrong?
To ensure correctness, Rollup will include any code that looks like it might have side-effects — to give a trivial example, this bundle would cause 'hello from foo.js' to be logged even though foo
isn't imported by main.js
:
/*--- main.js ---*/
import './foo.js';
/*--- foo.js ---*/
export function unused () {
// this will be omitted...
}
// but this will be included, because it has an effect on the world
console.log('hello from foo.js');
In the case of goodcore, everything looks to Rollup as though it might have side-effects. For example, Calc
is the result of calling _Calc()
, and since it's very hard to determine whether or not _Calc()
has effects, it must be included regardless of whether or not Calc
is used by the bundle. You can see this in the REPL.
Unfortunately, making this code treeshakeable would probably involve fairly substantial changes to the design. It's also possible that TypeScript is introducing non-treeshakeable constructs.