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

[IE11][Since 3.6.2] "SCRIPT5078: Cannot redefine non-configurable property 'find'" #790

Closed
erhanalankus opened this issue Mar 25, 2020 · 23 comments

Comments

@erhanalankus
Copy link

Hello,

We updated our packages and noticed that the scripts were not working on IE11.

The error message was "SCRIPT5078: Cannot redefine non-configurable property 'find'".

I tried each version of core-js, the issue appeared when we updated from 3.6.1 to 3.6.2.

This is the list of our dependencies, from package.json:

"dependencies": {
"@aspnet/signalr": "^1.1.4",
"@babel/runtime": "^7.8.7",
"@babel/runtime-corejs3": "^7.8.7",
"@glidejs/glide": "^3.4.1",
"axios": "^0.18.1",
"core-js": "3.6.1",
"haptics": "^1.0.0",
"iban": "0.0.12",
"intersection-observer": "^0.7.0",
"jarallax": "^1.12.0",
"lodash": "^4.17.15",
"mobx": "^5.15.4",
"nouislider": "^14.1.1",
"nprogress": "^0.2.0",
"numeral": "^2.0.6",
"perspective.js": "^1.0.0",
"qs": "^6.9.1",
"quill": "^1.3.7",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"redux-watch": "^1.1.1",
"regenerator-runtime": "^0.13.5",
"rellax": "^1.12.1",
"simple-parallax-js": "^5.3.0",
"sweetalert2": "^8.19.0",
"tooltip.js": "^1.3.3",
"validate.js": "^0.13.1",
"vanilla-lazyload": "^12.5.1"
}

Thank you for all your work.

@slowcheetah
Copy link
Contributor

Try to update to last version

@suspiciousfellow
Copy link

Getting same issue with latest version (albeit includes rather than find)

This appears to be related to two instances of corejs in the page.

@aardvarkk
Copy link

I'm also having this problem. No idea how to get around it at this point.

@slowcheetah
Copy link
Contributor

Can you give reproducible example?

@gempeler
Copy link

I have the same issue. I switched to version 3.4.0 - this works fine.

@Rohit-L
Copy link

Rohit-L commented Apr 27, 2020

Also seeing this on >= 3.6.2 for the "includes" method on IE11, switched to 3.6.1 for now.

@aardvarkk
Copy link

aardvarkk commented Apr 27, 2020

@slowcheetah I think I have more insight into this now.

In my case, I'm running a Ruby on Rails app. JavaScript processing is split into two: the asset pipeline and webpack. Our webpack JS relies on our asset pipeline JS executing first. Inside our asset pipeline JS we have an existing polyfill for Array.prototype.find in IE11. I'm not entirely sure on the history of it, but we must have added it to get some of the JS from the asset pipeline working properly. This is the exact code we have:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

If I have a webpack side that runs import 'core-js/stable' and an asset pipeline side that runs that polyfill, we see that error on IE11.

@aardvarkk
Copy link

I can also confirm that reverting to 3.6.1 fixes the error.

@DanishDeveloper360
Copy link

DanishDeveloper360 commented Jun 2, 2020

I am experiencing Cannot redefine non-configurable property 'includes'.

I have a webpack side that runs import 'core-js/stable', we see that error on IE11.

Reproducible even in core-js version 3.6.1

@amok
Copy link

amok commented Jun 16, 2020

Experiencing the same for a widget. Appears if core-js is included twice. I believe the issue can be considered as an important one. Any news on it?

@amok
Copy link

amok commented Jun 17, 2020

UPD
I did not manage to reproduce the bug including core-js twice (even with different or older versions)

Had to apply the following hotfix:

function isBrowserIEVersionBelowEdge() {
  return navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > -1;
}

function overrideObjectDefineProperty() {
  const defineProperty = Object.defineProperty;

  if (!defineProperty) {
    return;
  }

  Object.defineProperty = function (object, propertyName) {
    if (propertyName === 'includes' && Object.getOwnPropertyDescriptor) {
      const propertyDescriptor = Object.getOwnPropertyDescriptor(object, propertyName);

      if (propertyDescriptor && !propertyDescriptor.configurable) {
        // Do not redefine since it's gonna throw;
        return object;
      }
    }

    return defineProperty.apply(this, arguments);
  };
}

function applyWorkaround() {
  if (!isBrowserIEVersionBelowEdge()) {
    return;
  }

  try {
    overrideObjectDefineProperty();
  } catch (error) {
    console.error(error);
  }
}

applyWorkaround();

@VsevolodGolovanov
Copy link

Getting this error, because sometimes a polyfill (Array.includes) is already present from another place. Thing is, both core-js polyfills and those other polyfills are defined very globally in two different places, and intersect only in certain conditions. It's very hard for me to get rid of one - both are necessary at different times. I wish core-js wouldn't fail, if another polyfill is already present - in the end it doesn't matter to me, which one is actually active, because both of them implement things to the same spec.

@JakeChampion
Copy link
Contributor

Whichever polyfill is setting Array.prototype.find's descriptor to be non-configurable is incorrect and needs to either be corrected or removed.

Array.prototype.find is created using the abstract spec operation CreateMethodProperty which makes the property configurable.

Object.getOwnPropertyDescriptor(Array.prototype, 'find')
// returns: Object { value: find(), writable: true, enumerable: false, configurable: true }

@Miladiir
Copy link

Miladiir commented Sep 3, 2020

You have to realize that sometimes code runs in an environment that you have absolutely no influence on.

For example, at Inform, we develop extensions for Qlik Sense. Depending on the Qlik Sense Server version, different polyfills are already present. Since we (want to, have to) support a wide range of versions of QS we have to rely on our own polyfills.

The problem presented in this issue is the exact same one we are experiencing right now. Is there some way to catch the polyfill initialization errors?

Is there a reason why one might care about whether or not Array.prototype.find is polyfilled by our core-js version vs. whatever Qlik Sense or -vendor name here- polyfilled with?

@JakeChampion
Copy link
Contributor

You have to realize that sometimes code runs in an environment that you have absolutely no influence on.

I realise this as this project core-js runs in only environments we have no influence on and I also work on https://polyfill.io which runs only in environments I have no influence on.

Is there a reason why one might care about whether or not Array.prototype.find is polyfilled by our core-js version vs. whatever Qlik Sense or -vendor name here- polyfilled with?

There is no reason to care which polyfill is being used if they are all completely compliant with the specification. However this issue is showing that a polyfill being used is not specification compliant because it is marking the method as non-configurable when it is meant to be configurable.

@Miladiir
Copy link

Miladiir commented Sep 3, 2020

Thank you for your swift response. Also my comment sounded pretty harsh, for which I apologize. I am not a native speaker.

There is no reason to care which polyfill is being used if they are all completely compliant with the specification. However this issue is showing that a polyfill being used is not specification compliant because it is marking the method as non-configurable when it is meant to be configurable.
Okay, I get that. However, I am still lost as to what we should do in our code and/or our babel + core-js + webpack setup to remedy the issue.

The problematic polyfill is already present in servers, that will probably not get an update to fix that issue within the next year or so. Nothing I can do about it and completely in the hands of the customers.
Our code, that injects core-js, must now run on these machines as well as machines that are more up-to-date.

We currently use babel with the following (pretty standard) configuration:

{
  presets: [
      ["@babel/env", {
        useBuiltIns: "usage",
        modules: "commonjs",
        corejs: 3,
      }]
  ]
}

We support old browsers including IE11 and use webpack to bundle. From my understanding our code could not control which polyfills would be imported during runtime, because at the point at which our code execution starts, polyfills would have been already initialized. In our case this means on problematic QS Versions, the error in this issue would be thrown and our code will never run.

So do you, or anyone else know how to fix this? Maybe with core-js-pure?

@JakeChampion
Copy link
Contributor

The problematic polyfill is already present in servers, that will probably not get an update to fix that issue within the next year or so. Nothing I can do about it and completely in the hands of the customers.

I understand that, I would still love to know which package is providing the polyfill so that I can fix the source of the problem whilst also working around the problem from within core-js.

So do you, or anyone else know how to fix this? Maybe with core-js-pure?

I reckon adding a workaround in core-js is okay to do

@JakeChampion
Copy link
Contributor

In the past we can see issues like this one have been closed without any changes being made to core-js. #746

@Miladiir
Copy link

Miladiir commented Sep 3, 2020

I understand that, I would still love to know which package is providing the polyfill so that I can fix the source of the problem whilst also working around the problem from within core-js.

I will look into it. I unfortunately do not have access to source code, so I will do what I can.

I reckon adding a workaround in core-js is okay to do

That would be seriously awesome.

In the past we can see issues like this one have been closed without any changes being made to core-js. #746

I saw that aswell. Seems like zloirock changed his mind a couple of times for some reason.

@Miladiir
Copy link

Miladiir commented Sep 3, 2020

I found this:

DXp7: function (e, t) {
    Array.prototype.includes || Object.defineProperty(Array.prototype, 'includes', {
        value: function e(t, n) {
            if (null == this) throw new TypeError('"this" is null or not defined');
            if ('undefined' === typeof n) return -1 !== this.indexOf(t);
            var r = this.slice(n);
            return -1 !== r.indexOf(t)
        }
    })
},

Notice the missing options object. I can unfortunately not identify, where this part of the code comes from. All I can tell is, that the lines above are already executed on the page before my code is run.

@Miladiir
Copy link

Miladiir commented Sep 3, 2020

I just noticed, my colleague is also messaging you on #845. The two issues are the same.

@jorgutdev
Copy link

I had the same issue on IE11. Nothing worked until I changed to core-js v2

npm install --save core-js@2

babel.config.js

module.exports = function (api) {
  api.cache(true);

  return {
    presets: [
      ['@babel/preset-env', {
        debug: false,
        corejs: 2,
        targets: {
          browsers: ['ie 11, not dead']
        }
      }]
    ],
    plugins: [
      '@babel/transform-runtime',
      '@babel/plugin-proposal-class-properties'
    ]
  };
};

@zloirock
Copy link
Owner

It's an issue with an alternative incorrect 3rd party Array#find polyfill which defined as non-configurable and which does not pass core-js feature detection. core-js tries to fix it, but can't delete the previous implementation. It's a bug in this 3rd party polyfill, it's not a core-js issue.

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