Giter VIP home page Giter VIP logo

babel-plugin-transform-decorators-legacy's People

Contributors

amilajack avatar bathos avatar callumlocke avatar ide avatar jayphelps avatar loganfsmyth avatar teameh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

babel-plugin-transform-decorators-legacy's Issues

Class properties work differently with transform-decorators-legacy

Turning on transform-decorators-legacy will cause errors if you use class properties in a specific way.

class Foo {
  static SECOND = 1000;
  static MINUTE = Foo.SECOND * 60;
}

This will say that Foo is undefined while trying to evaluate Foo.SECOND. Without the decorators-legacy plugin this works.

Not working with mobx simple app

I am working on a project using mobx + react. And I need to use decorators. But I am getting an Uncaught TypeError: decorator is not a function in the Chrome console after Webpack bundle. Webpack shows no errors.

My webpack loader.

{
  test: /\.js$/,
  exclude: /(node_modules|bower_components)/,
  loader: 'babel', // 'babel-loader' is also a legal name to reference
  cacheDirectory: true,
  query: {
    plugins: [
      "transform-decorators-legacy",
    ],
    presets: ['react', 'es2015', 'stage-1']
  }
}

My dependencies:

"devDependencies": {
  "babel-cli": "^6.10.1",
  "babel-core": "^6.10.4",
  "babel-loader": "^6.2.4",
  "babel-plugin-transform-decorators-legacy": "^1.3.4",
  "babel-preset-es2015": "^6.9.0",
  "babel-preset-react": "^6.11.1",
  "babel-preset-stage-1": "^6.5.0",
  "mobx": "^2.3.6",
  "mobx-react": "^3.5.0",
  "react": "^15.2.1",
  "react-dom": "^15.2.1",
  "webpack": "^1.13.1"
}

Some further investingation points to this plugin. The errors pops out in the _applyDecoratedDescriptor method.

Am I missing something?

Decorator bug with target parameter

Hi Logan - I think I found a bug with the target parameter of a decorator. The target is supposed to return the class associated for the decorator.

A decorator on the class level works fine, I get an function back that I can instantiate.

A decorator on the method level returns back an Object of the class that I cannot instantiate.

function dec(debug) {
  return (target, property, descriptor) => {
    console.log(debug);
    console.log(target);
  }
}

@dec('from class:')
class A {

  @dec('from method:')
  doSomething(){

  }
}

Console output:

from method:
> A {}

from class:
> function A () {
   _classCallback(this, A);
}

I believe the target should be consistent where methods and classes get the same target. The target I received from the class level is what's useful to me here since I can't instantiate the other.

Thanks!

[QUESTION] Is it possible to overwrite the method of the target?

Is it possible to overwrite the implementation of some method? Overriding the property on the target does not really overwrite the method, like this:

function dec(id) {
    function exec(target, property, descriptor) {
      console.log('Prototype', target.prototype);

      target[property] = function() {
        console.log('executed', id);
      };
    }

    return exec;
}

class Example {
    @dec(1)
    method() {
      console.log('Method called');
    }
}

let example = new Example();

example.method();

This code still prints "Method called". Also, there is no prototype in target.
Is it possible to overwrite the method of the target somehow?

Thanks,

decorated class's constructor not called

'use strict';
function classDecorator(Target) {
  return class DecoratedClass extends Target {
    constructor(a) {
      console.log(a);
      super(a);
    }
  };
}

@classDecorator
class Test {
  static create() {
    return new Test(1);
  }
}

Test.create();

in babel 5, it will output 1, but not in this plugin.

.babelrc:

{
  "plugins": [
    "transform-decorators-legacy"
  ]
}

webpack.config.js need change

decorators only work when adding plugins: [ 'transform-decorators-legacy' ] in jsx loader of webpack.config.js . Is it a must?if so, please add to the Usage Doc.

Class-decorator not evaluated on initial render?

I've upgraded from Babel 5 to Babel 6 and use your plugin to build this react-anything-sortable-example with gulp and browserify:

import React from 'react';
import Sortable from 'react-anything-sortable';
import { sortable } from 'react-anything-sortable';

@sortable
class DemoHOCItem extends React.Component {
  render() {
    return (
      <div {...this.props}>
        {this.props.children}
      </div>
    );
  }
}

export default DemoHOCItem;

class Test extends React.Component {
  constructor() {
    super();
    this.state = {
      items: ['four','five','six']
    };
  }

render() {
    function renderWithSortable(renderItem, index) {
      return (
        <DemoHOCItem className="vertical" sortData="renderItem" key={index} dynamic>
          {console.log('rendering with sortable')}
          {renderItem+' sortable'}
        </DemoHOCItem>
      );
    }

    return (
      <div className="demo-container">
         <Sortable className="vertical-container" direction="vertical">
          {this.state.items.map(renderWithSortable, this)}
        </Sortable>
      </div>
    );
  }
};

export default Test;

On the initial rendering of <DemoHOCItem/> I get this warning:

main.js:28024 Warning: Unknown props `sortData`, `onSortableItemMount`, `onSortableItemReadyToMove`, `sortable`, `sortHandle` on <div> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop
    in div (created by DemoHOCItem)
    in DemoHOCItem (created by SortableItem)
    in SortableItem (created by Test)
    in div (created by Sortable)
    in Sortable (created by Test)
    in div (created by Test)
    in Test (created by RoutingContext)
    in div (created by App)
    in App (created by RoutingContext)
    in RoutingContext (created by Router)
    in Router

also when dragging an sortable item for the first time:

main.js:28024 Warning: Unknown prop `isDragging` on <div> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
    in div (created by DemoHOCItem)
    in DemoHOCItem (created by SortableItem)
    in SortableItem (created by Test)

Subsequent renderings (Without reloading the app) no longer produce warnings, so the sortable-module does its magic.

My guess is that the "sortable"-decorator is not evaluated on the first render, therefore React does not know what to do with all the functions provided by <div {...this.props}> in DemoHOCItem.render()

Is there something I can do to get rid of the warning?

Decorator incorrectly applies to nested class if used before export default

If a class decorator is used before export default and the class contains a nested class definition, the decorator applies to that nested class instead.

Steps to reproduce:

package.json:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {},
  "devDependencies": {
    "babel-cli": "^6.18.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.4"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

wrong.es6 (the @id decorator is applied before export default)

const id = _ => _;

class Parent {
}

@id
export default class Sample {
        method() {
                class Child extends Parent {
                }

                return Child;
        }
}

Output:

./node_modules/.bin/babel --plugins transform-decorators-legacy wrong.es6
const id = _ => _;

let Parent = class Parent {};
let Sample = class Sample {
        method() {
                var _class;

                let Child = id(_class = class Child extends Parent {}) || _class;

                return Child;
        }
};
export { Sample as default };

The decorator incorrectly applies to the nested class Child

right.es6 (the decorator is applied after export.default)

const id = _ => _;

class Parent {
}

export default @id class Sample {
        method() {
                class Child extends Parent {
                }

                return Child;
        }
}

Output:

./node_modules/.bin/babel --plugins transform-decorators-legacy right.es6
var _class;

const id = _ => _;

let Parent = class Parent {};


export default id(_class = class Sample {
        method() {
                let Child = class Child extends Parent {};


                return Child;
        }
}) || _class;

I expected transpiling wrong.es6 to either throw an error or apply @id to Parent

Class property decorator leads to TypeError

Here is my code:

import 'babel-core/register'
import 'babel-polyfill'

function Input() {
  return () => {}
}

class A {
  @Input() b;
  constructor() {}
}

window.a = new A()

It compiles into:

   function Input() {
  return function () {};
}

var A = (_class = function A() {
  _classCallCheck(this, A);

  this.b = _init.apply(this);
}, (_desc = Input()(_class.prototype, 'b', _desc = {
  enumerable: true,
  configurable: true,
  writable: true,
  initializer: null
}) || _desc, _init = _desc.initializer), _class);

window.a = new A();

Which looks fine at first, but then...
Uncaught TypeError: Cannot read property 'apply' of null

Here it is:

this.b = _init.apply(this);

It is a part of not implemented yet behavior? I really need it for Input() decorators in ng-forward.

Cannot assign to read only property of object

I have such error: Cannot assign to read only property 'name' of object '#<Category>' when I use non initialized properties decorated with decorators and then trying to assign values to these properties.

import {Entity, PrimaryColumn, Column} from "typeorm";

@Entity()
export class Category {

    @PrimaryColumn("int", { generated: true })
    id;

    @Column("string")
    name;

}

Solution is to do it this way:

import {Entity, PrimaryColumn, Column} from "typeorm";

@Entity()
export class Category {

    @PrimaryColumn("int", { generated: true })
    id = undefined;

    @Column("string")
    name = "";

}

Which is ugly. I guess the reason is that it does not make descriptor writable. Is there any better solution for this problem?

Method decorators

Thanks for this plugin. It sucks that a lot of React infrastructure started using decorators and now Babel isn't supporting it. I'm a little confused from the docs and the thread on Phabricator if decorating methods is supported by this plugin.

In my app I have this decorator for toggling classes on the react render method. Works fine with Babel 5 but chokes with Babel 6. Please let me know if I'm doing something wrong or if this behavior is not supported

//.babelrc
{
  "presets": ["react", "es2015", "stage-0"],
  "env": {
    "development": {
      "plugins": [
        "rewire",
        "transform-runtime",
        "transform-decorators-legacy",
        "typecheck",
        ["react-transform",
          {
          "transforms": [{
            "transform": "react-transform-hmr",
            "imports": ["react"],
            "locals": ["module"]
          }, {
            "transform": "react-transform-catch-errors",
            "imports": ["react", "redbox-react"]
          }]
        }]
      ]
    },
    "production": {
      "plugins": [
        "transform-runtime",
        "transform-decorators-legacy",
        "typecheck"
      ]
    }
  }
}
//decorator.js
import React from 'react';
import _ from 'lodash';
import cx from 'classnames';

export default function(...args) {
  /*eslint no-use-before-define:0*/
  let decArgs;

  if (args.length === 1) {
    //if the decorator is called with an `omit` argument then return the function
    decArgs = args[0];
    return decorate;
  } else if (args.length === 3) {
    //if the decorator is called with by the method with no initial arguments
    return decorate.apply(null, args);
  }

  function decorate(target, key, descriptor) {
    return {
      ...descriptor,
      value(...args) {
        const {someFluxProp, anotherFluxProp} = this.props;
        const {omit} = decArgs || {};
        const Comp = descriptor.value.apply(this, args);

        const className = cx(_.assign({}, makeClasses(Comp.props.className), _.omit({
          'step-current': anotherFluxProp,
          'is-hidden': someFluxProp
        }, omit)));

        return React.cloneElement(Comp, {className});
      }
    };
  }
}
SomeClass extends React.Component {
    @addClassDec({omit: 'is-hidden'})
    render() {
       return <div className="whatevs" />
    }
}

When I do this I get output:

ERROR in ./src/js/components/sample.jsx
Module parse failed: /Users/davidfox-powell/dev/frontend-boilerplate/node_modules/babel-loader/index.js?{"presets":["react","es2015","stage-0"],"plugins":["transform-decorators-legacy","transform-runtime","typecheck",["react-transform",{"transforms":[{"transform":"react-transform-hmr","imports":["react"],"locals":["module"]},{"transform":"react-transform-catch-errors","imports":["react","redbox-react"]}]}]]}!/Users/davidfox-powell/dev/frontend-boilerplate/node_modules/eslint-loader/index.js!/Users/davidfox-powell/dev/frontend-boilerplate/src/js/components/sample.jsx Line 3: Unexpected token
You may need an appropriate loader to handle this file type.
| 'use strict';
|
| import _Object$defineProperty from 'babel-runtime/core-js/object/define-property';
|
| var _dec, _dec2, _class, _desc, _value, _class2, _class3, _temp;

async method named "get"

When you name a async method get and try to decorate it, it will get called whenever it is referenced and not function as expected.

let decorator = target => {
    return target;
};

class Example {
	@decorator async get () {
		console.log('called');
	}
}

let instance = new Example();
typeof instance.get;

Class properties and decorators not playing well

I don't have enough insight to determine if this is due to babel 6 transform-class-properties or transform-decorators-legacy, but there is inconsistencies when migrating from babel5 decorators.

I created a sample project to demonstrate it: https://github.com/themouette/demo-decorators-classprops

Static properties are applied to the decorated class instead of the original class.

Current generated code looks like:

// ...
var Test = decorator(_class = function () {
  function Test() {
    _classCallCheck(this, Test);
  }

  _createClass(Test, [{
    key: 'render',
    value: function render() {
      return 'foo';
    }
  }]);

  return Test;
}()) || _class;

Test.propTypes = {
  foo: 'Hello'
};
// ...

When it should look someting like:

// ...
_class = function () {
  function Test() {
    _classCallCheck(this, Test);
  }

  _createClass(Test, [{
    key: 'render',
    value: function render() {
      return 'foo';
    }
  }]);

  return Test;
}()) || _class;

_class.propTypes = {
  foo: 'Hello'
};

var Test = decorator(_class);
// ...

Am I doing something wrong?

Class self scope error

class User {

    static func = User

}

console.log(User.func) // undefined

Its error

Example, a use ORM and i cant declarate database structure types

class User extends Model {

    static schema = {
        name: String,
        age: String,
        friends: [User], // User is undefined
    }

    // this code will be located in constructor
    name = User.createRandomName() // i cant call this

}

plugin is apparently ignored during transpilation

I've included the plug-in in my webpack config, but I'm still seeing "Decorators are not supported yet in 6.x pending proposal update" errors during transpilation.

Here is the related webpack loader:

{
    test: /\.js/,
    loader: 'babel',
    exclude: /node_modules/,
    query: {
        plugins: ['transform-decorators-legacy'],
        presets: ['es2015', 'react', 'stage-0']
    }
}

Relevant parts of my package.json are:

{
    "babel-cli": "6.3.17",
    "babel-core": "6.3.13",
    "babel-loader": "6.2.0",
    "babel-plugin-rewire": "1.0.0-beta-3",
    "babel-plugin-transform-decorators-legacy": "1.3.1",
    "babel-preset-es2015": "6.3.13",
    "babel-preset-react": "6.3.13",
    "babel-preset-stage-0": "6.3.13"
}

All decorators in my project are class-level, for example:

@Foo()
export default class Bar

...and

@Do(Something)
export default class Bar

It seems like I shouldn't see the "Decorators are not supported yet in 6.x pending proposal update" message with this plugin installed. Am I doing something wrong?

Update readme to reflect recent changes?

TC39 now says decorators are stage 2. Could this plugin's readme be updated to reflect the current status?

My impression (after an hour of reading conflicting info in various readmes) is that decorators are now well and truly on the standards track, and we're now waiting for an official Babel plugin. But I'm not clear on whether the official plugin will be essentially the same as this 'legacy' one, or if they will work differently. In other words I want some guidance on whether I should start using decorators today via this plugin - will it be easy to switch?

If you know the current situation it would be great to explain it the 'why legacy' section in this readme.

Breaks browserify debug

When running in babelify with browserify debug option set to true it leads to error in generating source map.

Decorator applied to base class instead of target class

If i have a base class, extend it, then apply a decorator to the property of that new class, the base class and all the classes that extend from it have that decorator. It seems to be an issue from applying the decorator to the prototype, which is the base class. I'm not sure if this is a babel issue or this plugin's issue.

From the generated code:

_applyDecoratedDescriptor(_class2.prototype, 'logo', [_dec3], {
	enumerable: true,
	configurable: true,
	initializer: function initializer() {
		return '';
	}
})

_class2 is the new class, and _class2.prototype is the base class. the decorator gets applied to the base class and all of it's children, adding the property to the children.

Error: We don't know what to do with this node type .....

Since this is a legacy/maintain old functionality plugin, I'm just reporting this, I realise it may not be worth fixing, the plugin is great anyway and has saved me a lot of trouble :)

The following (stripped down a bit) works:

import CSSModules from 'react-css-modules' ;
import styles from './accordion.css' ;
export function layoutAccordion (Header, Content) {
    class __Accordion extends React.Component {
        ....
        }
    return CSSModules(__Accordion, styles) ;
    }

but the decorated version doesn't:

import CSSModules from 'react-css-modules' ;
import styles from './accordion.css' ;
export function layoutAccordion (Header, Content) {
    @CSSModules(styles)
    class __Accordion extends React.Component {
        ....
        }
    return __Accordion
    }

The full error:

Error: app/layout/accordion.js: We don't know what to do with this node type. We were previously a Statement but we can't fit in here?
    at NodePath.insertBefore (/usr/lib/node_modules/babel-cli/node_modules/babel-core/node_modules/babel-traverse/lib/path/modification.js:62:13)
    at NodePath.unshiftContainer (/usr/lib/node_modules/babel-cli/node_modules/babel-core/node_modules/babel-traverse/lib/path/modification.js:254:15)
    at Scope.push (/usr/lib/node_modules/babel-cli/node_modules/babel-core/node_modules/babel-traverse/lib/scope/index.js:1031:41)
    at Scope.generateDeclaredUidIdentifier (/usr/lib/node_modules/babel-cli/node_modules/babel-core/node_modules/babel-traverse/lib/scope/index.js:308:10)
    at /home/mike/applify2/node_modules/babel-plugin-transform-decorators-legacy/lib/index.js:27:56
    at Array.map (native)
    at applyEnsureOrdering (/home/mike/applify2/node_modules/babel-plugin-transform-decorators-legacy/lib/index.js:25:53)
    at PluginPass.ClassExpression (/home/mike/applify2/node_modules/babel-plugin-transform-decorators-legacy/lib/index.js:223:38)
    at newFn (/usr/lib/node_modules/babel-cli/node_modules/babel-core/node_modules/babel-traverse/lib/visitors.js:278:19)
    at NodePath._call (/usr/lib/node_modules/babel-cli/node_modules/babel-core/node_modules/babel-traverse/lib/path/context.js:76:18)

Cannot Decorate Class Properties

When using babel-plugin-transform-class-properties any decorated class property is undefined

function myDecorator(){
    // Decorate stuff
}
...
class Person{
    @myDecorator
    age = 43; // Nope - doesn't work

    @myDecorator
    toString(){ // Yep - works
    }
    constructor(){
        console.log(this.age) // undefined
    }
}

Furthermore, the decorator is never called for the class property. Am I missing something?

Repetitive code in each module

Is there any chance that this transform will be smart enough to keep it's code in separate module, like "transform-runtime" does?

Of course, it's not necessary to joyfully use it – just to be, you know, and ideal tool =)

Unexpected character '@'

Hello,

I have the error: Parsing error: Unexpected character '@'. I am not sure what is wrong.

the code is:
import ui from 'redux-ui';
**@**ui({})

my configuration is:
{
"parser": "babel-eslint",
"extends": ["eslint:recommended", "plugin:react/recommended"],
"env": {
"es6": true,
"browser": true,
"node": true
},
"plugins": ["react"],
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"modules": true,
"jsx": true
}
},
"rules": {
"eqeqeq": [2, "allow-null"],
"jsx-quotes": 2,
"react/display-name": 2,
"react/jsx-curly-spacing": [2, "never"],
"react/self-closing-comp": 2,
"react/jsx-indent-props": [2, 2],
"react/jsx-no-duplicate-props": 2,
"no-console":0,
"strict": 0
}
}

I am using this plugins and presets:
presets: ["es2015", "react", "stage-0"],
"plugins": ["babel-plugin-transform-decorators-legacy", "transform-runtime"]

Decorators in source code

The source code includes @decorators, which are not officially supported by babel and the only way to make them work is by introducing "babel-plugin-transform-decorators-legacy".
Can we please rewrite code to include them in a more vanilla style?

Wrong? target with class functions decorators

For class functions decorators the target argument is not an actual reference to the real class but a reference to an instance, sounds weird to me. Is it correct/intended?

let assert = require('assert');
let fnTarget = null;
let fnTargetConstructor = null;

function fnDec(target, methodName, descriptor) {
  fnTarget = target;
  fnTargetConstructor = target.constructor;
  return descriptor;
}

class A {
  @fnDec
  doSomething() {}
}

assert(fnTarget !== A);
assert(fnTargetConstructor === A);

My package.json:

    "babel-core": "^6.11.4",
    "babel-plugin-transform-decorators-legacy": "1.3.4"

My .babelrc:

{
  "plugins": [
    "transform-decorators-legacy"
  ]
}

When initializer runs

It's a little unclear as to when instance members' initializers are run.
There are two functions in the transpiled code: _initDefineProp, and _applyDecoratedDescriptor.
Both may run initializers.
While the _initDefineProp runs initializer with this bound to a class instance,
the _applyDecoratedDescriptor runs initializer (if it decides to run it) with this bound to a class constructor function.

E.g. I was trying to create a decorator @BindThis that would bind function to this instance during construction.

class My { @BindThis() mouseclick(e) {...} }

BindThis had to replace value with initializer like this:
'function() { return originalFn.bind(this); }'

Unfortunately this initializer is called at _applyDecoratedDescriptor where this is constructor.

Can you please clarify?
Thanks.

decorator breaks class name resolving in static properties

this works:

class MyClass {
    static MY_CONSTANT = 'foo';
    static MY_ANOTHER_CONSTANT = {
        [MyClass.MY_CONSTANT]: 'bar',
    };
}

but it won't work after enabling transform-decorators-legacy: Cannot read property 'MY_CONSTANT' of undefined.

Decorators which take in parameters don't work

I am using Material-UI for my react application.
Here is an example from their documentation
This doesn't work after compiling with this plugin.

import MyRawTheme from 'path/to/your/raw/theme/file';
import ThemeManager from 'material-ui/lib/styles/theme-manager';
import ThemeDecorator from 'material-ui/lib/styles/theme-decorator';
const theme = ThemeManager.getMuiTheme(MyRawTheme);

@ThemeDecorator(theme)
class MyComponent extends Component {
}
export default MyComponent;

However this works

export default ThemeDecorator(theme)((MyComponent));

Decorator not applied on same react child components

var count = 0;

@connect(state => ({
    products: state.products
}))
export default class ParameterNode extends React.Component {
    constructor(props, context) {
      super(props, context);
      console.log('props', props);
    }

    render() {
        count = count + 1;

        if(count < 5) {
            return <ParameterNode />;
        }
        else {
            return <div></div>;
        }
    }

}

And the console output:

props Object {products: Object}
props Object {}
props Object {}
props Object {}
props Object {}

On the babel 5 it's ok.

ReferenceError: Unknown plugin - When deploying to CI sever (Cadetship)

Hi

Am getting the Unknown plugin error when deploying to CI server. Do you have any idea what could be the cause?

My webpack configuration is following:

var webpack = require('webpack');

var babelSettings = { presets: ['react', 'es2015', 'stage-0'] };
babelSettings.plugins = ['transform-decorators-legacy'];

module.exports = {
  entry: './entry',
  module: {
    loaders: [
      { test: /\.tsx?$/, loader: 'babel?' + JSON.stringify(babelSettings) + '!awesome-typescript', exclude: /node_modules|lib/ },
      { test: /\.jsx?$/, loader: 'babel', query: babelSettings, exclude: /node_modules/ },
      { test: /\.css$/, loader: 'null' },
      { test: /\.(png|jpe?g)(\?.*)?$/, loader: 'url?limit=8182' },
      { test: /\.(svg|ttf|woff2?|eot)(\?.*)?$/, loader: 'file' }
    ]
  }
};

if (process.env.NODE_ENV !== 'production') {
  var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
  module.exports.plugins = [new ForkCheckerPlugin()]
}

This is the error I am recieveing:

Errors prevented bundling:
While processing files with webpack:webpack (for target web.browser):
entry/client/webpack.conf.js: ./entry/client/entry.js
Module build failed: ReferenceError: Unknown plugin
"transform-decorators-legacy" specified in "base" at 0, attempted to resolve
relative to
"/home/rof/src/github.com/tomitrescak/kickstart-flowrouter/entry/client"
at
/home/rof/src/github.com/tomitrescak/kickstart-flowrouter/.meteor/local/webpack-npm/node_modules/babel-core/lib/transformation/file/options/option-manager.js:193:17

[Feature request] Support decorating static properties

Disclaimer: thanks a lot for taking the time and effort to implement this, I know you tried your best to provide us with a tentative implementation regardless of the decorator spec being questioned at the time.

It seems that this implementation currently doesn't support decorating static properties; I couldn't find any reference to them in either the source or the tests. Do you plan to add support for them in the near future?

Class decorator doesn't work

I have a following code, but the decorator is not called.

const sandbox = (...args) => (target) => {
  target.prototype = new Sandbox(...args);
};

// Docorator doesn't work
// @sandbox(child, {
//   perimeters: [
//     perimeter
//   ]
// })
class MyClass {}
// but this works
sandbox(child, {
  perimeters: [
    perimeter
  ]
})(MyClass);

Here is my package.json:

// ...
    "babel-cli": "^6.11.4",
    "babel-core": "^6.11.4",
    "babel-eslint": "^6.1.1",
    "babel-plugin-check-es2015-constants": "^6.3.13",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-es2015-arrow-functions": "^6.3.13",
    "babel-plugin-transform-es2015-block-scoped-functions": "^6.3.13",
    "babel-plugin-transform-es2015-block-scoping": "^6.3.13",
    "babel-plugin-transform-es2015-classes": "^6.3.13",
    "babel-plugin-transform-es2015-computed-properties": "^6.3.13",
    "babel-plugin-transform-es2015-destructuring": "^6.3.13",
    "babel-plugin-transform-es2015-for-of": "^6.3.13",
    "babel-plugin-transform-es2015-function-name": "^6.3.13",
    "babel-plugin-transform-es2015-literals": "^6.3.13",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.3.13",
    "babel-plugin-transform-es2015-object-super": "^6.3.13",
    "babel-plugin-transform-es2015-parameters": "^6.3.13",
    "babel-plugin-transform-es2015-shorthand-properties": "^6.3.13",
    "babel-plugin-transform-es2015-spread": "^6.3.13",
    "babel-plugin-transform-es2015-sticky-regex": "^6.3.13",
    "babel-plugin-transform-es2015-template-literals": "^6.3.13",
    "babel-plugin-transform-es2015-unicode-regex": "^6.3.13",
    "babel-plugin-transform-object-rest-spread": "^6.3.13",
    "babel-preset-es2015": "^6.6.0",
    "babel-register": "^6.3.13",
    "babelify": "^7.2.0",
    "browserify": "^13.0.1",
// ...

and .babelrc:

{
  "plugins": [
    ["transform-es2015-template-literals", { "loose": true }],
    "transform-es2015-literals",
    "transform-es2015-function-name",
    "transform-es2015-arrow-functions",
    "transform-es2015-block-scoped-functions",
    ["transform-es2015-classes", { "loose": true }],
    "transform-es2015-object-super",
    "transform-es2015-shorthand-properties",
    ["transform-es2015-computed-properties", { "loose": true }],
    ["transform-es2015-for-of", { "loose": true }],
    "transform-es2015-sticky-regex",
    "transform-es2015-unicode-regex",
    "check-es2015-constants",
    ["transform-es2015-spread", { "loose": true }],
    "transform-es2015-parameters",
    ["transform-es2015-destructuring", { "loose": true }],
    "transform-es2015-block-scoping",
    "transform-object-rest-spread",
    "transform-decorators-legacy"
  ],
  "env": {
    "commonjs": {
      "plugins": [
        ["transform-es2015-modules-commonjs", { "loose": true }]
      ]
    },
    "es": {
      "plugins": [
        "./build/use-lodash-es"
      ]
    }
  }
}

Decorating generator functions, impossible?

Just stumbled across this one

function decorator(target, attr, descriptor)
{
    return descriptor;
}


class Foo
{
    @decorator
    * gen() { yield 1; }
}

will result in the following error

SyntaxError: src/test.es: Unexpected token (xx:xx)
  xx |     @decorator
> xx |     *gen() { yield 1; }

Is this by design or can this be fixed?

Because, when doing this instead

class Foo
{
    @decorator
    async gen() {}
}

the decorator will be applied just fine.

And, by looking at the spec, in 14.3 it states that the GeneratorDefinition from 14.4 is a valid MethodDefinition.

And according to https://github.com/wycats/javascript-decorators#grammar PropertyDefinition refers to MethodDefinition.

Decorators with class properties cause Babel's classCallCheck to fail

I have the following code:

import React, from 'react'
import { observer } from 'mobx-react'

@observer
class OrgsPage extends React.Component {
  render = () =>
    <div>Hello</div>
}
export default OrgsPage

When I try and use this as a component in React I get:

babel-runtime.js?hash=71fe7d0…:108 Uncaught TypeError: Cannot call a class as a function
    at classCallCheck (http://localhost:4000/packages/babel-runtime.js?hash=71fe7d0d01dc808e2a80cb0a7958fb31e46323d5:108:13)
    at Constructor.OrgsPage (http://localhost:4000/app/app.js?hash=7ba134c41c0997baa4644e0e7b2750d3c4341f2f:1794:37)
    at Constructor.render (http://localhost:4000/packages/modules.js?hash=58c8b0b77d6bd50615c786bc9f20afd954ec52db:129542:32)
    at Object.allowStateChanges (http://localhost:4000/packages/modules.js?hash=58c8b0b77d6bd50615c786bc9f20afd954ec52db:116825:15)
    at Reaction.<anonymous> (http://localhost:4000/packages/modules.js?hash=58c8b0b77d6bd50615c786bc9f20afd954ec52db:129440:44)
...

This does not happen if I do any of the following:

  • Remove @observer
  • Change the render method to be a normal method (not a class property)
  • Have render as a normal method and add in another class property under a different name

My .babelrc:

{
  "presets": [
    "react",
    "es2015",
    "stage-3"
  ],
  "plugins": [
    "transform-decorators-legacy",
    "transform-class-properties"
  ]
}

And (what I think is) relevant package.json:

    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-stage-0": "^6.16.0",

This was working for me, and then updated some of my npm packages (like babel-preset-es2015) and then it stopped working. But npm being npm I can't see to get my node_modules back into that state again to prove it's a change between 6.16.0 and 6.18.0 of babel-preset-es2015.

class decorator works different from babel5

function classDecorator(Target) {
  return class DecoratedClass extends Target {
    test() {
      return 'decorated';
    }
  };
}

@classDecorator
class Test {
  static test() {
    return 'original';
  }

  static run() {
    // `Test` is not the *decorated* class here, but it is in bebel 5.
    console.log(Test.test());
  }
}

Test.run();

In bebel 5, it will return 'decorated', in this plugin, it return 'original'.

Why legacy?

Why decorators was removed from Babel?
I use it in many projects.

function Hack(classTarget) {
  classTarget.prototype.method = function() {
    console.log("Echo:", this.echo);
  }
}


@Hack
class Random {
  constructor() {
    this.echo = "Entropy";
  }
}


let obj = new Random();
obj.method();

v1.3.0 seems broken

Hello @loganfsmyth, thanks again for your dedication.

It seems that v1.3.0 may be broken, related to importing _Object$defineProperty.

In this gist you will find my original test source, and its transpiled version with v1.2.0 and v1.3.1. In the output of v1.3.0, the following line is present:

import _Object$defineProperty from 'babel-runtime/core-js/object/define-property';

I get the following error when I run the file:

import _Object$defineProperty from 'babel-runtime/core-js/object/define-property';
^^^^^^

SyntaxError: Unexpected token import
    at exports.runInThisContext (vm.js:54:16)
    at Module._compile (module.js:375:25)
    at Object.Module._extensions..js (module.js:406:10)
    at Module.load (module.js:345:32)
    at Function.Module._load (module.js:302:12)
    at Module.require (module.js:355:17)
    at require (internal/module.js:13:17)

I've checked my babel config and babel-plugin-transform-es2015-modules-commonjs is after babel-plugin-transform-decorators-legacy though. v1.2.0 still works fine for the given example.

Any idea what could cause this? Is there any way I can contribute?

transform-decorators-legacy bug

From: https://phabricator.babeljs.io/T2645

@loganfsmyth: I tried on the day of the latest release a few days ago, but had to stop because I couldn't get it to work with mobservable. I'm trying again today and trying to track down the problems....

First problem: Uncaught Error: Decorating class property failed. Please ensure that transform-class-properties is enabled my .babelrc has stage-1 enabled:

{
  presets: ['es2015', 'stage-1', 'react'],
  plugins: ['add-module-exports',  'transform-decorators-legacy']
}

If I manually add transform-class-properties (maybe I'm configuring incorrectly?) I do not get the warning:

{
  presets: ['es2015', 'stage-1', 'react'],
  plugins: ['add-module-exports', 'transform-class-properties', 'transform-decorators-legacy']
}

but I run into a second problem:

class MyClass {
  @observable hello = {things: []};

  @observable get world() { return this.hello.things; }
}

The world decorator is added, but the hello one is missing from the class decoration section. So it looks like there is a change / bug in how decorators handle class properties...(other more simple ones like @observable hello = null; are skipped too)

Have any idea to remove decorator for testing

@listensToClickOutside()

export default class myClass extends Component {

}

to

export default class myClass extends Component {

}

I read the babel-handbook and use 'babel-plugin-syntax-decorators'

image

this is my import code:

image

and output:

image

I don't see any decorator...have any idea@@?

Decorators not applied on non-inline functions in object literals

The current transformation treats functions in object literals differently depending on whether they are inlined or referenced. I am trying to apply a simple wrapper decorator to functions in an object literal, as in this example:

function decorator(target, name, descriptor) {
  const original = descriptor.value;
  descriptor.value = function decorated() {
    console.log(`wrapper: ${name}`);
    return original(...arguments);
  };
}

function foo() {
  console.log('foo');
}

const obj = {
  // Referenced function is not decorated
  @decorator foo,
  // Inline function is decorated
  @decorator bar() {
    console.log('bar');
  }
};

I would expect these syntaxes to work identically, but they do not:

obj.foo();
// "foo"
obj.bar();
// "wrapper: bar"
// "bar"

I found a workaround, but it's fairly ugly, because it needs to refer to the initializer property of the descriptor, which seems to be internal to this plugin:

function decorator(target, name, descriptor) {
  const original = descriptor.initializer ?
    descriptor.initializer() :
    descriptor.value;
  delete descriptor.initializer;
  descriptor.value = function decorated() {
    console.log(`wrapper: ${name}`);
    return original(...arguments);
  };
}

Decorating properties with computed names

Decorating class properties with computed names throws an error during compilation and class properties whose names are strings will generate code which will throw an error with the message: Decorating class property failed. Please ensure that transform-class-properties is enabled..

Google-ing for that error turned up issue #13 and looking through the other issues #59 seems to actually be the same problem.

I'd like to add the reproduction cases from the attached gist to the unit test but I am not confident enough I'll be able to actually solve this issue by myself. :)

See this gist for all the files: Decorating properties with computed names

Wrong scope for decorators variable

I'm encountering a bug due to a wrong scope variable definition.
I have a component:

@props({
 label: React.PropTypes.string,
 className: React.PropTypes.string,
 style: React.PropTypes.object
})
class Component extends React.Component {
 render() {
  const { label, ...props } = this.props;

  return (
  <div {...props}>
   {label}
  </div> 
  );
 }
}

but in render method props variable is equal to function es7PropsDecorator(type, options) { ... }, while with babel@^5 works just fine.

Apparent incompatibility with 6.5.0

I don't have a minimal test case yet, but this babelrc works pre-6.5.0, and throws this error with 6.5.0:

ModuleBuildError: Module build failed: SyntaxError: /project/ui/views/Component.jsx: Decorators are not supported yet in 6.x pending proposal update.

The .babelrc:

{
  "presets": [
    "es2015",
    "stage-0",
    "react",
    "async-to-bluebird"
  ],
  "plugins": [
  ]
}

Edit: Appears at this time that putting the plugin in the babelrc (and not in babel-loader's query) fixes the issue.

Cannot decorate Symbol expression members

Using a decorator on a Symbol class member throws:

function C(target, property, descriptor) {
   return descriptor;
}

const B = Symbol();

class A {

   @C
   [B] = null;

}

The following error, in the above case:

                       return decorator(target, property, desc) || desc;
                               ^

TypeError: decorator is not a function

Is this intended to work?

I see in the current decorators spec (2.1.1 - 1. Let propKey be the result of evaluating propertyName), this will work once that reaches implementation, but is there a specific reason not to for the legacy transform (would it break existing modules, was it explicitly disallowed in the original proposal)?

missing comment of first decorated method in class

I have compiled this

class Foo{

 /**
 * method 1
 */
 @decorator
 method1(){
  return "method1";
 }

 /**
 * method 2
 */
  method2(){
    return "method2";
  }

}

I got

var Foo = (_class = function () {
  function Foo() {
    _classCallCheck(this, Foo);
  }

  _createClass(Foo, [{
    key: "method1",
    value: function method1() {
      return "method1";
    }

    /**
    * method 2
    */

  }, {
    key: "method2",
    value: function method2() {
      return "method2";
    }
  }]);

  return Foo;
}(), (_applyDecoratedDescriptor(_class.prototype, "method1", [decorator], Object.getOwnPropertyDescriptor(_class.prototype, "method1"), _class.prototype)), _class);

missing /** method1 **/

how to use with webpack

Apologies ... but I can't figure out how I should enable this plugin in Webpack.
I tried adding it like this

{
    test: /\.jsx?$/,
    exclude: /node_modules/,
    loader: 'babel',
    query: {
      presets: [
        'es2015',
        'react',
        'stage-0'
      ]
    },
    plugins: ['transform-decorators-legacy']
  }

but I still get the error Decorators are not supported yet in 6.x pending proposal update.

String literal properties

Glad to have found this! There's a case where it's failing for me, which is when a method name is quoted (due to being a reserved word). I'm not familiar with Babel internals so I don't know exactly where this occurs but I think it may be here -- looks like it expects property names to always be naked string literals?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.