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

Exception: Cannot set property matchMedia of [object Object] which has only a getter #18774

Closed
1 task done
drush opened this issue Sep 11, 2019 · 7 comments · Fixed by #18828
Closed
1 task done

Exception: Cannot set property matchMedia of [object Object] which has only a getter #18774

drush opened this issue Sep 11, 2019 · 7 comments · Fixed by #18828
Assignees
Labels
🤔 Need Reproduce We cannot reproduce your problem

Comments

@drush
Copy link

drush commented Sep 11, 2019

  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

https://gist.github.com/drush/22bbd7134f4a54d96b811b170de72d9e

Steps to reproduce

Have not been able to reproduce, although can see this exception thrown in FE crash reports across several different browsers over several weeks of app operation in production.

What is expected?

An exception should not be thrown.

Simple tests in console make it appear that window.matchMedia is settable, but have not been able to identify if there are lockdown browser features or an extension that might be overriding this.

What is actually happening?

window.matchMedia = window.matchMedia || matchMediaPolyfill;

throws an exception. We see this in production across Chrome and Edge - all on Windows so far. Affecting at least 10 different versions of Chrome (60-76) and 2 versions of Edge.

Cannot set property matchMedia of [object Object] which has only a getter

This same code appears in:
Sider, Carousel and responsiveObserve
https://github.com/ant-design/ant-design/search?q=%22window.matchMedia %3D%22&unscoped_q=%22window.matchMedia %3D%22

It seems that in some cases, the window.matchMedia attribute cannot be set. This may be some additional enterprise security setting, or other locked-down feature in the browser that some users have turned on.

SUGGESTED REMEDY:

  • Store the matchMedia attribute or polyfill in a local variable, or a new non-reserved attribute on window, ie window.xxMatchMedia
Environment Info
antd 3.23.2
React 16.8.4
System Windows
Browser Chrome/Edge

This earlier case reports the same issue but did not provide repro details: #15289

@drush
Copy link
Author

drush commented Sep 11, 2019

@Chidi3b3r3 Please add any comments you have on this issue as I believe you have seen it as well.

@ant-design-bot
Copy link
Contributor

Hello @drush. Please provide a online reproduction by forking this link https://u.ant.design/codesandbox-repro or a minimal GitHub repository. Issues labeled by Need Reproduce will be closed if no activities in 7 days.

你好 @drush, 我们需要你提供一个在线的重现实例以便于我们帮你排查问题。你可以通过点击 此处 创建一个 codesandbox 或者提供一个最小化的 GitHub 仓库。7 天内未跟进的 issue 将会被自动关闭。

@afc163 afc163 added the 🤔 Need Reproduce We cannot reproduce your problem label Sep 12, 2019
@ztplz
Copy link
Contributor

ztplz commented Sep 12, 2019

If it only happen in production environment? In some case Babel generates properties with only get defined for re-exported object. Anyway, having a mini repo will make it easier for me to debug. Or you can tell me which components are used in your app that are causing the problem.

@drush
Copy link
Author

drush commented Sep 12, 2019

We are seeing this error in the Sider: node_modules/antd/es/layout/Sider.js:147

We have not been able to reproduce in production or development, but are seeing a steady stream of these exceptions in our production crash reports.

The Babel re-exported object thought is interesting. Do you know if the window object gets re-exported?

Here are browser versions where we can see it occurring
image

@drush
Copy link
Author

drush commented Sep 12, 2019

Our stack uses webpack and babel (7.3.4 ATM). This issue references the 'babel re-export only getters' issue
https://docs.w3cub.com/javascript/errors/getter_only/
https://stackoverflow.com/questions/53162001/typeerror-during-jests-spyon-cannot-set-property-getrequest-of-object-which

Tried this to attempt a repro in the console, but could not get it to fail.

(function()
{
    'use strict';
    window.myvar = true;
    window.mediaMatch = {'hello': 'world'};
    console.log('done without errors');
}());

@drush
Copy link
Author

drush commented Sep 12, 2019

FWIW this refactor would fix the issue regardless:

// window.matchMedia = window.matchMedia || matchMediaPolyfill;
if(!window.matchMedia) window.matchMedia = matchMediaPolyfill;

@ztplz
Copy link
Contributor

ztplz commented Sep 13, 2019

The properties of window in the browser can be changed, it is not read-only.
image

But the window in your project may become read-only due to some code or configuration reasons.
e.g. When we re-exported something
in typescript
image
transform to javascript via babel
image
Test in Chrome
image

The reason we have to re-assign matchMedia is because we need to use polyfill compatible with ie9.
https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
image
So these codes can work because it will only be reassigned in ie9

But antd 4.0 will no longer support ie9 and ie10, this hack will not be necessary.

We can force assignment by defineProperty.

// when ie9
if(!window.matchMedia) {
   Object.defineProperty(window, 'matchMedia', {
    enumerable: true,
    configurable: true,
    writable: true,
   value: matchMediaPolyfill
 });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤔 Need Reproduce We cannot reproduce your problem
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants