babel decorators (in legacy mode) expect the property descriptor to be returned rather than be defined within the decorator, TS also supports this feature.
checkout https://github.com/mzeiher/lit-element-test
npm install
npm run build
open index.html
both elements are updated (one decorated with TS the other with babel decorators in legacy mode)
only the TS version works
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?
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.
Most helpful comment
I figured out a working implementation of the
@propertydecorator for Babel 7 (and latest decorators proposal, i.e. non-legacy mode):