Ответ 1
tl; dr Если вы находитесь на Babel 6, вы можете использовать https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
Расширение встроенных типов, таких как Array
и Error
, и таких никогда не поддерживалось в Babel. Это совершенно справедливо в реальной среде ES6, но есть требования, чтобы заставить его работать, что очень сложно перевести таким образом, который совместим со старыми браузерами. Он "работал" в Babel 5 в том смысле, что он не выдавал ошибку, но объекты, созданные из расширенного подкласса, не работали, как предполагалось, например:
class MyError extends Error {}
var e1 = new MyError();
var e2 = new Error();
console.log('e1', 'stack' in e1);
console.log('e2', 'stack' in e2);
приводит к
e1 false
e2 true
Пока он не выходил из строя, подкласс не получает должным образом "стек", как предполагается. Аналогично, если бы вы расширили Array
, он мог бы вести себя как массив и иметь методы массива, но он не вел себя полностью как массив.
Документация Babel 5 специально назвала это краеугольным камнем классов, о которых нужно знать.
В Babel 6 классы были изменены, чтобы быть более spec-compliant в том, как обрабатывается подклассы, а побочным эффектом является то, что теперь вышеуказанный код все равно не будет работать, но он не будет работать иначе, чем до. Это описано в https://phabricator.babeljs.io/T3083, но я расскажу здесь о потенциальном решении.
Чтобы вернуть поведение подкласса Babel 5 (помните, все еще не правильно или рекомендуется), вы можете поместить встроенный конструктор в свой собственный временный класс, например.
function ExtendableBuiltin(cls){
function ExtendableBuiltin(){
cls.apply(this, arguments);
}
ExtendableBuiltin.prototype = Object.create(cls.prototype);
Object.setPrototypeOf(ExtendableBuiltin, cls);
return ExtendableBuiltin;
}
С помощью этого помощника вместо выполнения
class MyError extends Error {}
делать
class MyError extends ExtendableBuiltin(Error) {}
В вашем конкретном случае, однако, вы сказали, что находитесь на Node 5.x. Node 5 поддерживает собственные классы ES6 без пересылки. Я бы рекомендовал вам использовать их, сбросив пресет es2015
и вместо этого используя node5
, чтобы вы, среди прочего, получали родные классы. В этом контексте
class MyError extends Error {}
будет работать так, как вы ожидаете.
Для людей, не входящих в Node 4/5 или только в Chrome, вам может потребоваться использовать что-то вроде https://www.npmjs.com/package/error. Вы также можете изучить https://www.npmjs.com/package/babel-plugin-transform-builtin-extend. Параметр approximate
от этого является тем же самым поведением из Babel 5. Остерегайтесь того, что поведение не approximate
определенно красноречиво и может не работать в 100% случаев.