Lit-element: lit decorators doesnt work with babel legacy mode decorators

Created on 18 Sep 2018  路  14Comments  路  Source: Polymer/lit-element

babel decorators (in legacy mode) expect the property descriptor to be returned rather than be defined within the decorator, TS also supports this feature.

Steps to Reproduce

checkout https://github.com/mzeiher/lit-element-test

npm install
npm run build
open index.html

Expected Results

both elements are updated (one decorated with TS the other with babel decorators in legacy mode)

Actual Results

only the TS version works

Browsers Affected

  • [ x] Chrome
  • [ x] Firefox
  • [ x] Edge
  • [ x] Safari 11
  • [ x] Safari 10
  • [ x] IE 11

Versions

  • lit-element: v0.6.1
  • webcomponents: v2.1.3
Medium Bug

Most helpful comment

I figured out a working implementation of the @property decorator for Babel 7 (and latest decorators proposal, i.e. non-legacy mode):

export function property(options) {
    return elementDescriptor => {
        const name = elementDescriptor.key
        // key generation code copied from https://github.com/Polymer/lit-element/blob/master/src/lib/updating-element.ts
        const key = typeof name === 'symbol' ? Symbol() : `__${name}`
        return {
            // We are creating an own property and using the original initializer, but changing the key,
            // so foo becomes __foo. The getter and setter methods are created by createProperty().
            ...elementDescriptor,
            key,
            finisher(clazz) {
                clazz.createProperty(name, options)
            }
        }
    }
}

All 14 comments

i prepared a pull request to support the babel decorators

Related #174

Decorators don't work in Babel7, I think they work in Babel6

i prepared a pull request to support the babel decorators

Do you have a link to the PR?

206

I started investigating how this could work in Babel 7 with the latest decorators proposal. I'll post back here if I have time to work on it more, but this inspired me to make this comment on the proposal repo which might be of interest:
https://github.com/tc39/proposal-decorators/issues/85#issuecomment-427618739

I figured out a working implementation of the @property decorator for Babel 7 (and latest decorators proposal, i.e. non-legacy mode):

export function property(options) {
    return elementDescriptor => {
        const name = elementDescriptor.key
        // key generation code copied from https://github.com/Polymer/lit-element/blob/master/src/lib/updating-element.ts
        const key = typeof name === 'symbol' ? Symbol() : `__${name}`
        return {
            // We are creating an own property and using the original initializer, but changing the key,
            // so foo becomes __foo. The getter and setter methods are created by createProperty().
            ...elementDescriptor,
            key,
            finisher(clazz) {
                clazz.createProperty(name, options)
            }
        }
    }
}

@mbrowne I had the same problem with my library, I wrote all my decorators according to the stage2 API and for legacy and babel compatibility I created a small helper to use the stage2 decorators also in legacy mode (https://github.com/mzeiher/ce-decorators/blob/master/src/stage2/stage2decorators.ts) the decorators probe if a stage2 or legacy is expected and apply either the native s2, or transform the request to a s2 compatible one (don't know if it works on all edge cases, it works for me at the moment with TS decorators (also patched Reflect.decorate to let TS apply multiple decorators (https://github.com/mzeiher/ce-decorators/blob/master/src/reflect.ts)) Babel legacy and Babel-stage2. maybe you can include this logic into lit-element? Or create maybe I can publish the helper as a separate library...

Is this also why I'm currently seeing (in latest release) that my use of @property decorators does not trigger render?

@ernsheong Yep

Dup of #156

Re-opening as we've had a couple more requests. I'm not sure when we can get to this though, so contributions welcome.

From #921

I think we can make it work by checking the arguments to the decorators more carefully.

Sometime ago, i did some tests with possible decorator setups (babel6, babel7/legacy babel7/spec, typescript): https://github.com/blikblum/lit-element-decorator-tests

You can look at compiled files like https://github.com/blikblum/lit-element-decorator-tests/blob/master/babel7/dist/main-legacy.js#L2258

At the time i come to the conclusion that is not possible to use property decorator with babel/legacy and that typescript was working by accident (it is/was setting the property instead of defining it)

How to reproduce with a project on github pwa-webpack-starter-kit. If you run the project using npm install && npm run start everything will work OK. If you change the babel configuration from
['@babel/proposal-decorators', { decoratorsBeforeExport: true, }],
to
['@babel/proposal-decorators', { legacy: true, }],
The elements won't be rendered.

Struggling with this in a project that uses NX where I can't override { decoratorsBeforeExport: true } in the babel config built into their build system. I've opened a ticket but if there are other paths to resolution I'd appreciate any help, I was stumped on why the property changes weren't updating the updating the view for a long time.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PotterDai picture PotterDai  路  4Comments

vdegenne picture vdegenne  路  4Comments

erikkroes picture erikkroes  路  3Comments

chrismbeckett picture chrismbeckett  路  3Comments

antonioaltamura picture antonioaltamura  路  4Comments