有没有办法防止将 Class 转译到构造函数?

Is there a way to prevent transpile Class to constructor?

我有一个 node.js 应用程序使用 Flow。为了摆脱 Flow 语法,我使用了 babel:

{
    "presets": ["env", "flow"],
    "plugins":  [
        "transform-flow-strip-types"
    ]
}

它可以工作,但问题是使用 "instanceof" 运算符。我像这样扩展了标准错误构造函数:

/* @flow */
class BadRequestError extends Error {
    constructor(message:string) {
        super(message);
    }
}

class InvalidRequestBodyError extends Error {
    constructor(message:string) {
        super(message);
    }
}

class UnauthorizedError extends Error {
    constructor(message:string) {
        super(message);
    }
}

class ExpiredResourceError extends Error {
    constructor(message:string) {
        super(message);
    }
}

class InternalServerError extends Error {
    constructor(message:string) {
        super(message);
    }
}

class ResourceNotFoundError extends Error {
    constructor(message:string) {
        super(message);
    }
}

module.exports = {
    BadRequestError,
    InvalidRequestBodyError,
    UnauthorizedError,
    ExpiredResourceError,
    InternalServerError,
    ResourceNotFoundError
};

在 Node.js 中有效。但是在转译之后,instanceof 不再起作用,因为 类 转换为 Constructors.

有什么办法可以预防吗?

使用 babel-cli@6.26.0 和 node@8.9.0,这是我使用的命令行:

$ node_modules/.bin/babel ./src -d ./dist

Babel preset-env documentation所述,

Without any configuration options, babel-preset-env behaves exactly the same as babel-preset-latest (or babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017 together).

这就是为什么 ES6 类 被转译为常规函数的原因。

此页面包含有关在节点中使用此预设的所有信息:

For convenience, you can use "node": "current" to only include the necessary polyfills and transforms for the Node.js version that you use to run Babel

应该是:

{
    "presets": ["env", {
      "targets": {
        "node": "current"
      }
    }, "flow"],
    "plugins":  [
        "transform-flow-strip-types"
    ]
}

我通过

解决了这个问题
  1. 添加babel-plugin-transform-builtin-extend
  2. 将 class 改成这样:

    class BadRequestError extends Error {
        constructor(message:string) {
        super(message);
    
            /* $FlowFixMe */
            this.constructor = BadRequestError;
            /* $FlowFixMe */
            this.__proto__ = BadRequestError.prototype;
        }
    }
    

注意后面跟this,会在Babel 7中修复!