Embrace ES Decorators

Gem's v1.x.x version supports TypeScript's experimental decorators, which provide a very user-friendly development experience. Now ES Decorator Proposal has entered the State 3 stage. Various browser vendors and build tools have implemented their own implementations. Starting from v2, Gem will be implemented using ES decorators. Custom elements you write in JavaScript also have good type support.

import { GemElement, customElement, html } from '@mantou/gem'; import { attribute, property, emitter } from '@mantou/gem'; @customElement('my-element') class MyElement extends GemElement { @attribute src; @property callback = () => {}; @emitter error; render = () => { return html`<div @click=${this.callback}>${this.src}</div>`; }; }

NOTE

  • esbuild >= 0.21.2, target don't use the default esnext
  • vite >= 5.3
  • typescript >= 5.0
  • Chrome bug track
  • Firefox bug track

Differences from TypeScript Decorator

TypeScript's field decorator is executed immediately after the class definition, making it easy to define accessor properties on the prototype object. The ES decorator must use accessor to achieve similar effects. Even using accessor will cause the Gem to lose some functions. So Gem uses a special way to implement it so that it looks no different from the TypeScript decorator, in fact, the initialization functions returned by these loaders will be run every time MyElement is instantiated. You can check the tsc compiled code:

let MyElement = (() => { return class MyElement extends _classSuper { src = __runInitializers(this, _src_initializers, void 0); }; })();

Use Decorator Metadata

v1.x uses many static attributes to record other characteristics of the style of elements. They will increase learning costs, so v2 uses them Decorator Metadata instead. When you need to obtain these features(such as Gem Devtools), can use the Symbol.metadata.

Pitfalls of using ES Decorators

@attribute no longer work through theobservedAttributes, but intercept the setAttribute. Do not use the modified setAttribute in DevTools, so modify the element attribute in DevTools cannot trigger the element update.

NOTE

Installing the browser extension Gem DevTools will solve this problem