Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/Prod inconsistency for Ember.Object.create().hasOwnProperty('_super') #12462

Closed
dschmidt opened this issue Oct 8, 2015 · 2 comments
Closed

Comments

@dschmidt
Copy link
Contributor

dschmidt commented Oct 8, 2015

Hey,

today I ran into an issue with our production builds being broken, which was ultimately caused by minified builds behaving differently to non-minified builds:
Ember.Object.create().hasOwnProperty('_super') is false in non-minified builds, but true in minified ones.

I've actually verified that building in production environment with minifyJS: { enabled: false } isn't making _super an 'own property'. So I assume it's a minification issue and nothing else that might differ for production and development builds.

We stumbled upon this because we were doing for in on an Ember.Object and checking the properties with hasOwnProperty. (yes, it's fishy. no, i don't think it's a good idea. yes, i've changed the code already, but the inconsisteny somewhere remains).

To show this behavior I prepared a demo project here:
https://github.com/dschmidt/ember-dev-prod-inconsistency
(It's just a completely empty project ... but any of your projects should be good)

Just run ember s and ember s --environment=production and compare the outputs of Ember.Object.create().hasOwnProperty('_super')

BR,
Domme

@rwjblue
Copy link
Member

rwjblue commented Oct 8, 2015

Just confirmed that hasOwnProperty('_super') is false when running debug or prod builds without minification and true when running minified builds.

@rwjblue
Copy link
Member

rwjblue commented Oct 8, 2015

OK, so I have tracked down the issue.

We check to see if a function contains _super / .call / .apply before attempting to super wrap a given method (this saves quite a bit of extra super wrapping for functions that do not need it). Unfortunately, a number of platforms that we support do not support calling func.toString() so we attempt to detect this and fall back to always super wrap everything mode.

We have roughly this code (from here) to detect if we can call toString() and get the original source:

  let sourceAvailable = (function() {
    return this;
  }).toString().indexOf('return this;') > -1;

This works perfectly for development builds, but unfortunately not when minified. Take a look at the minified source and you will see why:

var e=function(){return this}.toString().indexOf("return this;")>-1;

Note that minifier has stripped the trailing semicolon from the function body we are attempting to check against, but sadly our indexOf check still contains the semicolon!


tldr; We super wrap every function in uglified builds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants