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

@babel/preset-env doesn't handle native class such as Array correctly in some situations #9757

Open
herbix opened this issue Mar 24, 2019 · 5 comments

Comments

@herbix
Copy link

herbix commented Mar 24, 2019

Bug Report

Current Behavior
Using @babel/preset-env, target ie: 11.
When a class extends Array indirectly, all the methods disappears.

Input Code

function ClassFactory(superObj) {
    class ClassTemplate extends superObj {
        constructor() {
            super([1, 2]);
            this.k = 1;
            return this;
        }

        test() {
            console.log(this.k);
        }
    }

    return ClassTemplate;
}

class UsefulClass extends ClassFactory(Array) {
    constructor() {
        super();
        this.j = 1;
        return this;
    }

    test2() {
        console.log(this.j);
    }
}

const instance = new UsefulClass();
instance.test();        // Uncaught TypeError: p.test is not a function
instance.test2();
console.log(instance);

Expected behavior/code
The methods should exist.

Babel Configuration (.babelrc, package.json, cli command)

In webpack.config.json:

    module: {
        rules: [
            { test: /\.js$/, loader: "babel-loader", options: {
                presets: [
                    [
                        "@babel/preset-env",
                        {
                            targets: {
                                ie: 11
                            }
                        }
                    ]
                ]
            } }
        ]
    }

In package.json:

  "devDependencies": {
    "@babel/core": "^7.4.0",
    "@babel/polyfill": "^7.4.0",
    "@babel/preset-env": "^7.4.2",
    "@types/node": "^10.12.18",
    "@types/react": "^16.7.6",
    "@types/react-dom": "^16.0.9",
    "awesome-typescript-loader": "^5.2.1",
    "babel-loader": "^8.0.5",
    "copy-webpack-plugin": "^4.5.1",
    "es6-promise": "^4.2.5",
    "rimraf": "^2.6.2",
    "source-map-loader": "^0.2.4",
    "tslint": "^5.12.0",
    "tslint-eslint-rules": "^5.4.0",
    "typescript": "^3.2.2",
    "webpack": "^4.28.2",
    "webpack-cli": "^3.0.8",
    "webpack-dev-server": "^3.1.0",
    "worker-loader": "^2.0.0"
  },
  "dependencies": {
    "axios": "^0.18.0",
    "bootstrap": "^4.2.1",
    "ml-matrix": "^5.2.1",
    "qs": "^6.6.0",
    "react": "^16.7.0",
    "react-dom": "^16.7.0"
  }

Environment

  • Babel version(s): v7.4.0
  • Node/npm version: Node v10.15.0, npm v6.4.1
  • OS: Windows 10 1809
  • Monorepo: no
  • How you are using Babel: loader

Possible Solution
I noticed if a class directly extends Array, it will become _wrapNativeSuper(Array), but in my case, there're no _wrapNativeSuper. I believe it's the cause of the issue. I think babel could do this check when a variable is possibly a native class. Like:

(variable === Array ? _wrapNativeSuper(variable) : variable)

Additional context/Screenshots
Nop.

@babel-bot
Copy link
Collaborator

Hey @herbix! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community
that typically always has someone willing to help. You can sign-up here
for an invite.

@nicolo-ribaudo
Copy link
Member

How would you define "possibly a native class"?

I suggest using ClassFactory(class extends Array {}) to force Babel to use _wrapNativeSuper.

@herbix
Copy link
Author

herbix commented Mar 24, 2019

ClassFactory(class extends Array {}) is a great idea. But sample codes are from another library that I can't edit tem. I had to write a loader to do this trick.

I mean, when a class extends another class from variables or arguments, the super class might be Array. Should babel check whether it needs a _wrapNativeSuper first?

@nicolo-ribaudo
Copy link
Member

The problem is that we would need to load all this package at runtime: https://unpkg.com/globals@11.11.0/globals.json

@herbix
Copy link
Author

herbix commented Apr 1, 2019

Hmm. It seems to be impossible.
Is it possible to just give some warning message when extends variable happens?

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

No branches or pull requests

3 participants