Skip to content

Commit

Permalink
Draft of 3.0 prerelease 2 blog post
Browse files Browse the repository at this point in the history
  • Loading branch information
justinfagnani committed Sep 28, 2023
1 parent d78cc3a commit 0efa652
Showing 1 changed file with 133 additions and 0 deletions.
133 changes: 133 additions & 0 deletions packages/lit-dev-content/site/blog/2023-09-27-lit-3.0-prerelease-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
tags: blogPosts
layout: blog-post.html
title: "Lit 3.0 Prerelease 2 and more!"
summary: "Today we are publishing a second of prereleases for the upcoming Lit 3.0 launch."
date: 2023-09-27
author:
- justin-fagnani
---

# Lit 3.0 Prerelease 2 and more!

Today we are publishing a second of prereleases for the upcoming Lit 3.0 launch. This includes the core packages of `lit`, `lit-html`, and `lit-element`, prereleases for the Task, Context, and React packages that are graduating from Lit Labs, and previews of two exciting new Lit Labs packages: `@lit-labs/compiler` and `@lit-labs/preact-signals`.

The full list of prerelease packages is:
- `[email protected]`
- `[email protected]`
- `[email protected]`
- `@lit/[email protected]`
- `@lit/[email protected]`
- `@lit/[email protected]`
- `@lit/[email protected]`
- `@lit/[email protected]`
- `@lit-labs/[email protected]`
- `@lit-labs/[email protected]`

## Lit 3.0 Prerelease 2

As we [announced with the first prerelease](./2023-05-15-lit-3.0-prerelease/), Lit 3.0 is a breaking change that most notably removes support for IE11. Lit 3.0 is intended to have no new features, since new features can be added in non-breaking minor versions.

### New hybrid decorators with standard decorators support

One new thing we _have_ added to Lit 3.0 though is support for TC39 standard decorators. The new decorator spec has reached Stage 3 in TC39, meaning that browsers and compilers are now implementing them. This is a huge step for Lit because it allows us to begin the process of moving to decorator implementation that won't require a compiler to use.

Recently TypeScript 5.2 added support for standard decorator metadata, which was the last piece needed for us to use the new specification (Babel's next release will have support). So we've made our decorators work with TypeScript's `experimentalDecorators` flag set to either `true` or `false`.

The reason why we've included standard decorator support in a breaking change is that we've taken great care to make the upgrade path from experimental decorators smooth, and in order do that we've introduced a few minor breaking changes to our experimental decorator behavior to make the behavior consistent with the standard decorator behavior.

The big thing is that we've added support for decorating the new "auto-accessors" - fields prefixed with the `accessor` keyword. Auto-accessors create a getter/setter pair and private storage that they access. These are able to be overridden by standard decorators.

Standard decorators _require_ that fields use the `accessor` keyword. To facilitate incremental upgrades to standard decorators, we now supportm them in experimental decorators, so that the same callsite works with both settings:

```ts
class MyElement extends LitElement {
@property()
accessor myProperty = 'hello';
}
```

This means that you can upgrade your decorated fields to use `accessor`, and once they all are, you can turn off `experimentalDecorators`.

The breaking changes were required because it's not possible to differentiate between auto-accessors and hand-written accessors. Previously we wouldn't automatically call `this.requestUpdate()` for accessors, instead requiring the hand-written setter to call it manually. Now we do call `requestUpdate()` automatically. We also will read the value of an accessor on first render and use that as the initial value for `changedProperties` and attribute reflection.

This means that experimental decorators behave similarly for class fields and auto-accessors, but is a change from Lit 2.x.

## New Lit template compiler!

The releases today also include the first preview of our new template compiler. This is a TypeScript compiler transform that compiles lit-html templates into a prepared representation (by inserting binding markers and creating template parts) so that the template prep steps are skipped at runtime. This can improve first render performance, sometimes dramatically. All template behavior remains exactly the same.

We plan on offering the compiler in a number of tool plugin formats, but for now we just have a TypeScript transform. One of the easiest ways to use it is via Rollup's TypeScript plugin, which allows you to add transforms:

`rollup.config.js`:
```js
import typescript from '@rollup/plugin-typescript';
import {compileLitTemplates} from '@lit-labs/compiler';

export default {
// ...
plugins: [
typescript({
transformers: {
before: [compileLitTemplates()],
},
}),
// other rollup plugins
],
};
```

## Preact Signals integration

Signals are all the rage right now. For Lit developers Signals promise to offer a convenient and relatively simple option for shared observable state.

One issue that signals present for web components is that signals lack interoperability between implementations. This goes against the interoperability goals of web components, so for now, rather than build our own signals package or pick just one that we endorse, we plan on offering integration packages to be able to use signal libraries with Lit.

These integrations will be relatively simple because we have two straight-forward ways of using signals:
1. Treat a component's update lifecycle as an effect, so that it's run when any signals it accesses (like in templates) changes. This integrates signals with Lit's batching async lifecycle for good performance when many signals change.
2. Use a directive to wire a signal directly to a location in DOM.

The new `@lit-labs/preact-signals` package provides this integration for [Preact Signals](https://preactjs.com/guide/v10/signals/) which is published as a standalone library.

Our new package provides three ways to use signals:
1. A `SignalWatcher` mixin, which makes a component automatically watch all signals used during updates.
2. A `watch()` directive, which watches one signal and updates a binding with it.
2. A special `html` template tag that auto-applies the `watch()` directive to all bindings that use signals.

Here's an example of using the `SignalWatcher` mixin:

```ts
import {LitElement, html} from 'lit';
import {customElement, property} from 'lit';
import {SignalWatcher, signal} from '@lit-labs/preact-signals';

const count = signal(0);

@customElement('signal-example')
export class SignalExample extends SignalWatcher(LitElement) {
static styles = css`
:host {
display: block;
}
`;

render() {
return html`
<p>The count is ${count.value}</p>
<button @click=${this._onClick}>Increment<button></button></button>
`;
}

private _onClick() {
count.value = count.value + 1;
}
}
```

## Lit Labs graduation

We are also graduating our first set of Lit Labs packages: Context, Task, and React.

These packages have a new home in the `@lit` npm scope, but are otherwise exactly the same as the current labs version.

##

0 comments on commit 0efa652

Please sign in to comment.