File: README.md

package info (click to toggle)
node-babel-plugin-transform-decorators-legacy 1.3.5-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 184 kB
  • sloc: makefile: 7; sh: 2
file content (148 lines) | stat: -rw-r--r-- 4,374 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148


# Babel Legacy Decorator plugin

This is a plugin for Babel 6 that is meant to replicate the old decorator behavior from
Babel 5 in order to allow people to more easily transition to Babel 6 without needing to
be blocked on updates to the decorator proposal or for Babel to re-implement it.

## Babel >= 7.x

This plugin is specifically for Babel 6.x. If you're using Babel 7, this plugin is not for you.
Babel 7's `@babel/plugin-proposal-decorators` officially supports the same logic that this
plugin has, but integrates better with Babel 7's other plugins. You can enable this with

```json
{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
  ]
}
```
in your Babel configuration. Note that `legacy: true` is specifically needed if you
want to get the same behavior as `transform-decorators-legacy` because there
are newer versions of the decorator specification coming out, and they do not
behave the same way as this plugin does.


## Installation & Usage

    $ npm install --save-dev babel-plugin-transform-decorators-legacy

Add the following line to your .babelrc file:

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

#### NOTE: Order of Plugins Matters!
If you are including your plugins manually and using `transform-class-properties`, make sure that `transform-decorators-legacy` comes *before* `transform-class-properties`.

```js
/// WRONG

"plugins": [
  "transform-class-properties",
  "transform-decorators-legacy"
]

// RIGHT

"plugins": [
  "transform-decorators-legacy",
  "transform-class-properties"
]
```

## Why "legacy"?

Decorators are still only a relatively new proposal, and they are (at least currently) still
in flux. Many people have started to use them in their original form, where each decorator
is essentially a function of the form

    function(target, property, descriptor){}

This form is very likely to change moving forward, and Babel 6 did not wish to support
the older form when it was known that it would change in the future. As such, I created this
plugin to help people transition to Babel 6 without requiring them to drop their decorators
or requiring them to wait for the new proposal update and then update all their code.

## Best Effort

This plugin is a best effort to be compatible with Babel 5's transpiler output, but there
are a few things that were difficult to reproduce, and a few things that were simply incorrect
in Babel 5 with respect to the decorators proposal.

Two main things to mention as differences, though not things you are likely to encounter:

1. Decorators expressions are evaluated top to bottom, and executed bottom to top. e.g.

    ```
    function dec(id){
        console.log('evaluated', id);
        return (target, property, descriptor) => console.log('executed', id);
    }

    class Example {
        @dec(1)
        @dec(2)
        method(){}
    }
    ```

    In Babel 5, this would output:

    ```
    evaluated 2
    evaluated 1
    executed 2
    executed 1
    ```

    With this plugin, it will result in:

    ```
    evaluated 1
    evaluated 2
    executed 2
    executed 1
    ```

    which is what the spec dictates as the correct behavior and was incorrect in Babel 5.

2. Static class property initializers are evaluated once up front.

    If you decorate a static class property, you will get a descriptor with an `initializer` property.
    However whereas with Babel 5 this could be re-executed multiple times with potentially differing
    results, `decorators-legacy` will precompute the value and return an initializer that will
    return that value. e.g.

    ```
    function dec(target, prop, descriptor){
        let {initializer} = descriptor;
        delete descriptor.initializer;
        delete descriptor.writable;

        descriptor.get = function(){
            return initializer.call(this);
        };
    }

    var i = 0;

    class Example {
        @dec
        static prop = i++;
    }
    ```

    In Babel 5, every access to `prop` would increment `i`.
    In Babel 6, the very first value of `i` will be cached for future `initializer` calls.

    The spec is a little vague around how initializers work for repeat calls, and I'd consider
    calling an `initializer` multiple times to be a mistake in general, so hopefully this will
    not cause anyone trouble.

## License

MIT (c) 2015