-
Notifications
You must be signed in to change notification settings - Fork 12.8k
decoratorMetadataEmit not compatible with Babel's 6-to-5 #2836
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
Comments
I believe the core of the issue is that the emit for I do not have enough context for |
In current chrome, here is an interactive session:
|
@mhegazy, we have to manually assign the name of the class that has decorators due to the double-bind issue with class declarations. The problem is that the "name" property of Function has [[Configurable]]: true in ES6, but has [[Configurable]]: false in ES5 Chrome, as well as non-strict contexts in Chrome Canary with ES6 features enabled. @alexeagle Given Chrome's update cycle, how likely would it be that they make Function#name configurable by default before ES6 support ships? |
I have no idea. But for my part, as long as this is an isolated problem On Mon, Apr 20, 2015 at 3:16 PM Ron Buckton [email protected]
|
@alexeagle, I could change this from
|
I don't think this would help us in Closure, their runtime polyfill seems On Tue, Apr 21, 2015 at 11:44 AM Ron Buckton [email protected]
|
Fixed in #2897 |
FYI, I'm still seeing this on the 1.5 beta. |
@jamiewinder can you provide more details? this input: function dec() { }
@dec
export class Foo {
} on 1.5-beta gives me: if (typeof __decorate !== "function") __decorate = function (decorators, target, key, desc) {
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc);
switch (arguments.length) {
case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
}
};
function dec() { }
var Foo = (function () {
function Foo() {
}
Foo = __decorate([
dec
], Foo);
return Foo;
})(); |
Here's a basic reproduction, which uses TypeScript 1.5-beta, ES6 output, Babel, and SystemJS together: index.html <script src="system.js"></script>
<script>
System.transpiler = "babel";
System.babelOptions = {
modules: "system"
};
System.import("app");
</script> app.ts import { DecoratedClass } from './decoratedclass';
var dc = new DecoratedClass();
var dummy = dc.name; DecoratedClass.ts import { TestDecorator } from './testdecorator';
export class DecoratedClass {
@TestDecorator()
public get name(): string {
return "This is a test";
}
} TestDecorator.ts export function TestDecorator() {
return (target: any, key: string, props: PropertyDescriptor) => {
var getter = props.get;
props.get = function () {
var val = getter();
console.log(val);
return val;
};
};
} The expected result is that the 'This is a test' is written to the console (by the decorator). If I build as ES5 using a CommonJS module system, then it does exactly that. However, if I build to ES6, then I get an error:
Let me know if you need more information. |
@rbuckton looks like "use strict" issue |
I don't think the original issue is fixed. It's still the case that es6 emit produces Object.defineProperty which only works in Chrome Canary, not Chrome. We now need a proper fix as we are starting to use typescript to compile the decorator parts of Angular. |
I believe it's expected that
tsc -t es6
should be externally transpilable to ES5 (eg with Babel)See https://gist.github.com/alexeagle/24243fbb87dbd8bad6f1
Babel replaces the __decorate line
this.__decorate
withundefined.__decorate
so that gives a runtime error.Uncaught TypeError: Cannot read property '__decorate' of undefined app_bin.js:7
Note I also tried this with Closure Compiler ES6->ES5, and had a different problem because of this line in the emit:
Object.defineProperty(App, "name", { value: "App", configurable: true });
in ES6 spec, new objects are configurable:true by default, but in mainline Chrome it is configurable:false by default so this is also a runtime error. For this case, it leads me to wonder if ES5->ES6 transpilers should be expected to translate API incompatibilities in addition to new ES6 syntax.
The text was updated successfully, but these errors were encountered: