We just noticed that a single commit of ours which updates ember-cli-babel from 6.17.2 to 7.1.3, ember-cli-typescript from 1.5.0 to 2.0.0-beta.3 and ember-auto-import from 1.2.15 to 1.2.17 caused our production ES6 build to grow from 822.66 KB (130.52 KB gzipped) to 1.14 MB (152.94 KB gzipped). Not sure where the problem is but this is pretty major so I wanted to ask here for any ideas. How do we debug this? I'm willing to help with whatever I can.
P.S. This is our frontend.js file, not vendor.js.
My immediate guess is that this is tied to the helpers that Babel 7 emits for each module with decorators and the like being more verbose than they were in previous versions. The raw growth (38.6%) vs gzipped growth (16.9%) also points that direction (or at least an increase in repeated content in the output).
This is likely to come up across the broader Ember ecosystem as more folks upgrade to Babel 7 and as decorators become part of the core programming model for Ember. A while back @pzuraq was investigating ways to have Babel use shared importable versions of these helpers rather than emitting them separately for each module, but I don't know that anyone is actively working on that at the moment.
Got diverted from working on this, but should be back on it in the coming weeks!
So does this mean that this is going to be resolved as an issue at some point? And do you think it's OK to downgrade ember-cli-typescript until that time? Not that it matters that much but still it's 40%...
I鈥檒l see if I can handle it this week. It鈥檒l definitely be handled in the coming months, for sure
@boris-petrov so for what it's worth, we're upgrading ember-cli-typescript for better maintainability and integration with the ecosystem (especially things like ember-auto-import), but the current experience is quite solid in general. Hopefully we and @pzuraq can help Babel iterate on this to get it sorted sooner rather than later, but you should be just fine on the 1.x series.
Thank you all for the support! Let's hope that you can resolve the problem for everybody. :)
Work on externalized helpers: https://github.com/babel/ember-cli-babel/pull/251
@boris-petrov, ember-cli-babel 7.3.0-beta.1 should solve this. You will need to enable the new includeExternalHelpers option. Note that this is global and will affect the app and any addons that are using ember-cli-babel >= 7.3.0-beta-1. If you get a chance to try this, please report back here.
@jamescdavis - thanks! I'll be sure to try that some time next week. Will report back. :)
@jamescdavis - I updated ember-cli-babel to 7.3.0-beta.1 and ember-cli-typescript to 2.0.0-rc.1 and added this includeExternalHelpers option but when I try building the project, ember-cli blows up:
- broccoliBuilderErrorStack: TypeError: Cannot read property 'value' of undefined
at getKey (/home/boris/project/node_modules/@babel/helper-create-class-features-plugin/lib/decorators.js:70:56)
at File.extractElementDescriptor (/home/boris/project/node_modules/@babel/helper-create-class-features-plugin/lib/decorators.js:94:219)
at Array.map (<anonymous>:null:null)
at buildDecoratedClass (/home/boris/project/node_modules/@babel/helper-create-class-features-plugin/lib/decorators.js:133:62)
at PluginPass.Class (/home/boris/project/node_modules/@babel/helper-create-class-features-plugin/lib/index.js:135:51)
at newFn (/home/boris/project/node_modules/@babel/traverse/lib/visitors.js:193:21)
at NodePath._call (/home/boris/project/node_modules/@babel/traverse/lib/path/context.js:53:20)
at NodePath.call (/home/boris/project/node_modules/@babel/traverse/lib/path/context.js:40:17)
at NodePath.visit (/home/boris/project/node_modules/@babel/traverse/lib/path/context.js:88:12)
at TraversalContext.visitQueue (/home/boris/project/node_modules/@babel/traverse/lib/context.js:118:16)
at TraversalContext.visitQueue (/home/boris/project/node_modules/@babel/traverse/lib/context.js:124:21)
at TraversalContext.visitMultiple (/home/boris/project/node_modules/@babel/traverse/lib/context.js:85:17)
at TraversalContext.visit (/home/boris/project/node_modules/@babel/traverse/lib/context.js:144:19)
at Function.traverse.node (/home/boris/project/node_modules/@babel/traverse/lib/index.js:94:17)
at NodePath.visit (/home/boris/project/node_modules/@babel/traverse/lib/path/context.js:95:18)
at TraversalContext.visitQueue (/home/boris/project/node_modules/@babel/traverse/lib/context.js:118:16)
at TraversalContext.visitSingle (/home/boris/project/node_modules/@babel/traverse/lib/context.js:90:19)
at TraversalContext.visit (/home/boris/project/node_modules/@babel/traverse/lib/context.js:146:19)
at Function.traverse.node (/home/boris/project/node_modules/@babel/traverse/lib/index.js:94:17)
at traverse (/home/boris/project/node_modules/@babel/traverse/lib/index.js:76:12)
at transformFile (/home/boris/project/node_modules/@babel/core/lib/transformation/index.js:88:29)
at runSync (/home/boris/project/node_modules/@babel/core/lib/transformation/index.js:45:3)
at transformSync (/home/boris/projectel/core/lib/transform.js:43:38)
at Object.transform (/home/boris/project/node_modules/@babel/core/lib/transform.js:22:38)
at resolve (/home/boris/project/node_modules/ember-cli-babel/node_modules/broccoli-babel-transpiler/lib/parallel-api.js:254:26)
at initializePromise (/home/boris/project/node_modules/rsvp/dist/rsvp.js:520:5)
at new Promise (/home/boris/project/node_modules/rsvp/dist/rsvp.js:995:33)
at transformString (/home/boris/projectr-cli-babel/node_modules/broccoli-babel-transpiler/lib/parallel-api.js:253:12)
at Babel.transform (/home/boris/project/node_modules/ember-cli-babel/node_modules/broccoli-babel-transpiler/index.js:110:10)
at Babel.processString (/home/boris/project/node_modules/ember-cli-babel/node_modules/broccoli-babel-transpiler/index.js:212:15)
at /home/boris/project/node_modules/broccoli-persistent-filter/lib/strategies/persistent.js:41:23
at initializePromise (/home/boris/project/node_modules/broccoli-persistent-filter/node_modules/rsvp/dist/rsvp.js:567:5)
at new Promise (/home/boris/project/node_modules/broccoli-persistent-filter/node_modules/rsvp/dist/rsvp.js:1039:33)
at /home/boris/project/node_modules/broccoli-persistent-filter/lib/strategies/persistent.js:40:18
at tryCatch (/home/boris/project/node_modules/async-disk-cache/node_modules/rsvp/dist/rsvp.js:525:12)
at invokeCallback (/home/boris/project/node_modules/async-disk-cache/node_modules/rsvp/dist/rsvp.js:538:13)
at publish (/home/boris/project/node_modules/async-disk-cache/node_modules/rsvp/dist/rsvp.js:508:7)
at flush (/home/boris/project/node_modules/async-disk-cache/node_modules/rsvp/dist/rsvp.js:2415:5)
at process.internalTickCallback (internal/process/next_tick.js:70:11)
Should I have done something else? One thing that I noticed is that yarn upgrade still keeps ember-cli-babel 7.2.0 as a resolution for packages that depend on ember-cli-babel. Not sure if that matters or how can I make it do a different thing.
@boris-petrov can you file a proper bug report including your package.json and tsconfig.json for this new mode of failure?
- broccoliBuilderErrorStack: TypeError: Cannot read property 'value' of undefined
We have an issue template for build-related bugs to help gather information to reproduce these kinds of things.
OK, so the error above was because of this Babel issue so no need to open a new bug report here. With that fixed on my side, our build is now 866.91 KB (133.4 KB gzipped) which is very close to the one with version 1.5.0 of ember-cli-typescript (and it's been a month so perhaps it's normal for our build to have grown a bit). I'll be running tests now to see if all works fine and then I'll close the issue as resolved. Thank you all for the support!
I think all is fine on our side - tests are passing and all seems to work. Just a quick question before I close this - why is this still generating slightly bigger code than TypeScript? What is the difference now that all helpers are deduplicated?
There are two reasons that the code may be slightly bigger:
We are including _all_ babel helpers, regardless of whether or not they are used currently. This is a limitation in ember-cli currently, and rather than try to figure out a way to only include used helpers we're waiting on the tree-shaking efforts to come through and allow us to drop helpers (and any other code that code be tree-shaken)
Modern decorator code is still much bigger than TS's decorator code. Even if you were just including modern decorator helpers, if you only used them in one or two files it could still be more expensive than the TS decorator code.
@pzuraq - thank you for the detailed explanation and for the great work on this!
Most helpful comment
Work on externalized helpers: https://github.com/babel/ember-cli-babel/pull/251