@astrojs/lit
Advanced tools
Comparing version 0.0.0-experimental-assets-20230307131344 to 0.0.0-handle-unhandled-20231213142946
@@ -20,4 +20,4 @@ async function polyfill() { | ||
if (!polyfillCheckEl || !polyfillCheckEl.shadowRoot) { | ||
if (!polyfillCheckEl?.shadowRoot) { | ||
polyfill(); | ||
} |
@@ -10,3 +10,3 @@ import { readFileSync } from "node:fs"; | ||
"@webcomponents/template-shadowroot/template-shadowroot.js", | ||
"lit/experimental-hydrate-support.js" | ||
"@lit-labs/ssr-client/lit-element-hydrate-support.js" | ||
], | ||
@@ -13,0 +13,0 @@ exclude: ["@astrojs/lit/server.js"] |
@@ -1,1 +0,2 @@ | ||
import 'lit/experimental-hydrate-support.js'; | ||
// @ts-check | ||
import '@lit-labs/ssr-client/lit-element-hydrate-support.js'; |
{ | ||
"name": "@astrojs/lit", | ||
"version": "0.0.0-experimental-assets-20230307131344", | ||
"version": "0.0.0-handle-unhandled-20231213142946", | ||
"description": "Use Lit components within Astro", | ||
@@ -30,19 +30,37 @@ "type": "module", | ||
}, | ||
"files": [ | ||
"dist", | ||
"client-shim.js", | ||
"client-shim.min.js", | ||
"hydration-support.js", | ||
"server.js", | ||
"server-shim.js" | ||
], | ||
"dependencies": { | ||
"@lit-labs/ssr": "^2.2.0", | ||
"@lit-labs/ssr": "^3.2.0", | ||
"@lit-labs/ssr-client": "^1.1.5", | ||
"@lit-labs/ssr-dom-shim": "^1.1.2", | ||
"parse5": "^7.1.2" | ||
}, | ||
"overrides": { | ||
"@lit-labs/ssr": { | ||
"@lit-labs/ssr-client": "1.1.3" | ||
} | ||
}, | ||
"devDependencies": { | ||
"astro": "0.0.0-experimental-assets-20230307131344", | ||
"astro-scripts": "0.0.0-experimental-assets-20230307131344", | ||
"chai": "^4.3.6", | ||
"cheerio": "^1.0.0-rc.11", | ||
"lit": "^2.2.5", | ||
"mocha": "^9.2.2", | ||
"sass": "^1.52.2" | ||
"chai": "^4.3.7", | ||
"cheerio": "1.0.0-rc.12", | ||
"lit": "^3.1.0", | ||
"mocha": "^10.2.0", | ||
"sass": "^1.69.5", | ||
"astro": "0.0.0-handle-unhandled-20231213142946", | ||
"astro-scripts": "0.0.14" | ||
}, | ||
"peerDependencies": { | ||
"@webcomponents/template-shadowroot": "^0.1.0", | ||
"lit": "^2.1.3" | ||
"@webcomponents/template-shadowroot": "^0.2.1", | ||
"lit": "^3.1.0" | ||
}, | ||
"publishConfig": { | ||
"provenance": true | ||
}, | ||
"scripts": { | ||
@@ -49,0 +67,0 @@ "build": "astro-scripts build \"src/**/*.ts\" && tsc", |
@@ -12,2 +12,3 @@ # @astrojs/lit 🔥 | ||
Astro includes a CLI tool for adding first party integrations: `astro add`. This command will: | ||
1. (Optionally) Install all necessary dependencies and peer dependencies | ||
@@ -45,12 +46,12 @@ 2. (Also optionally) Update your `astro.config.*` file to apply this integration | ||
__`astro.config.mjs`__ | ||
```diff lang="js" "lit()" | ||
// astro.config.mjs | ||
import { defineConfig } from 'astro/config'; | ||
+ import lit from '@astrojs/lit'; | ||
```js ins={2} "lit()" | ||
import { defineConfig } from 'astro/config'; | ||
import lit from '@astrojs/lit'; | ||
export default defineConfig({ | ||
// ... | ||
integrations: [lit()], | ||
}); | ||
export default defineConfig({ | ||
// ... | ||
integrations: [lit()], | ||
// ^^^^^ | ||
}); | ||
``` | ||
@@ -61,2 +62,3 @@ | ||
To use your first Lit component in Astro, head to our [UI framework documentation][astro-ui-frameworks]. This explains: | ||
- 📦 how framework components are loaded, | ||
@@ -66,13 +68,8 @@ - 💧 client-side hydration options, and | ||
However, there's a key difference with Lit _custom elements_ over conventional _components_: you can use the element tag name directly. | ||
Writing and importing a Lit component in Astro looks like this: | ||
Astro needs to know which tag is associated with which component script. We expose this through exporting a `tagName` variable from the component script. It looks like this: | ||
__`src/components/my-element.js`__ | ||
```js | ||
// src/components/my-element.js | ||
import { LitElement, html } from 'lit'; | ||
const tagName = 'my-element'; | ||
export class MyElement extends LitElement { | ||
@@ -84,14 +81,11 @@ render() { | ||
customElements.define(tagName, MyElement); | ||
customElements.define('my-element', MyElement); | ||
``` | ||
> Note that exporting the `tagName` is __required__ if you want to use the tag name in your templates. Otherwise you can export and use the constructor, like with non custom element frameworks. | ||
Now, the component is ready to be imported via the Astro frontmatter: | ||
In your Astro template import this component as a side-effect and use the element. | ||
__`src/pages/index.astro`__ | ||
```astro | ||
--- | ||
import {MyElement} from '../components/my-element.js'; | ||
// src/pages/index.astro | ||
import { MyElement } from '../components/my-element.js'; | ||
--- | ||
@@ -102,7 +96,7 @@ | ||
> Note that Lit requires browser globals such as `HTMLElement` and `customElements` to be present. For this reason the Lit renderer shims the server with these globals so Lit can run. You *might* run into libraries that work incorrectly because of this. | ||
> Note that Lit requires browser globals such as `HTMLElement` and `customElements` to be present. For this reason the Lit renderer shims the server with these globals so Lit can run. You _might_ run into libraries that work incorrectly because of this. | ||
### Polyfills & Hydration | ||
The renderer automatically handles adding appropriate polyfills for support in browsers that don't have Declarative Shadow DOM. The polyfill is about *1.5kB*. If the browser does support Declarative Shadow DOM then less than 250 bytes are loaded (to feature detect support). | ||
The renderer automatically handles adding appropriate polyfills for support in browsers that don't have Declarative Shadow DOM. The polyfill is about _1.5kB_. If the browser does support Declarative Shadow DOM then less than 250 bytes are loaded (to feature detect support). | ||
@@ -113,3 +107,3 @@ Hydration is also handled automatically. You can use the same hydration directives such as `client:load`, `client:idle` and `client:visible` as you can with other libraries that Astro supports. | ||
--- | ||
import {MyElement} from '../components/my-element.js'; | ||
import { MyElement } from '../components/my-element.js'; | ||
--- | ||
@@ -134,15 +128,16 @@ | ||
These globals *can* interfere with other libraries that might use the existence of these variables to detect that they are running in the browser, when they are actually running in the server. This can cause bugs with these libraries. | ||
These globals _can_ interfere with other libraries that might use the existence of these variables to detect that they are running in the browser, when they are actually running in the server. This can cause bugs with these libraries. | ||
Because of this, the Lit integration might not be compatible with these types of libraries. One thing that can help is changing the order of integrations when Lit is interfering with other integrations: | ||
```diff | ||
import { defineConfig } from 'astro/config'; | ||
import vue from '@astrojs/vue'; | ||
import lit from '@astrojs/lit'; | ||
```diff lang="js" | ||
// astro.config.mjs | ||
import { defineConfig } from 'astro/config'; | ||
import vue from '@astrojs/vue'; | ||
import lit from '@astrojs/lit'; | ||
export default defineConfig({ | ||
- integrations: [vue(), lit()] | ||
+ integrations: [lit(), vue()] | ||
}); | ||
export default defineConfig({ | ||
- integrations: [vue(), lit()] | ||
+ integrations: [lit(), vue()] | ||
}); | ||
``` | ||
@@ -152,2 +147,11 @@ | ||
### Strict package managers | ||
When using a [strict package manager](https://pnpm.io/pnpm-vs-npm#npms-flat-tree) like `pnpm`, you may get an error such as `ReferenceError: module is not defined` when running your site. To fix this, hoist Lit dependencies with an `.npmrc` file: | ||
```ini | ||
# .npmrc | ||
public-hoist-pattern[]=*lit* | ||
``` | ||
### Limitations | ||
@@ -154,0 +158,0 @@ |
@@ -1,20 +0,35 @@ | ||
import { installWindowOnGlobal } from '@lit-labs/ssr/lib/dom-shim.js'; | ||
import { customElements as litCE, HTMLElement as litShimHTMLElement } from '@lit-labs/ssr-dom-shim'; | ||
if (typeof fetch === 'function') { | ||
const _fetch = fetch; | ||
installWindowOnGlobal(); | ||
globalThis.fetch = window.fetch = _fetch; | ||
} else { | ||
installWindowOnGlobal(); | ||
// Something at build time injects document.currentScript = undefined instead of | ||
// document.currentScript = null. This causes Sass build to fail because it | ||
// seems to be expecting `=== null`. This set to `undefined` doesn't seem to be | ||
// caused by Lit and only happens at build / test time, but not in dev or | ||
// preview time. | ||
if (globalThis.document) { | ||
document.currentScript = null; | ||
} | ||
window.global = window; | ||
document.getElementsByTagName = () => []; | ||
// See https://github.com/lit/lit/issues/2393 | ||
document.currentScript = null; | ||
if (globalThis.HTMLElement) { | ||
// Seems Astro's Element shim does nothing when `.setAttribute` is called | ||
// and subsequently `.getAttribute` is called. Causes Lit to not SSR attrs | ||
globalThis.HTMLElement = litShimHTMLElement; | ||
} | ||
const ceDefine = customElements.define; | ||
// Astro seems to have a DOM shim and the only real difference that we need out | ||
// of the Lit DOM shim is that the Lit DOM shim reads | ||
// `HTMLElement.observedAttributes` which is meant to trigger | ||
// `ReactiveElement.finalize()`. So this is the only thing we will re-shim since | ||
// Lit will try to respect other global DOM shims. | ||
globalThis.customElements = litCE; | ||
const litCeDefine = customElements.define; | ||
// We need to patch customElements.define to keep track of the tagName on the | ||
// class itself so that we can transform JSX custom element class definintion to | ||
// a DSD string on the server, because there is no way to get the tagName from a | ||
// CE class otherwise. Not an issue on client:only because the browser supports | ||
// appending a class instance directly to the DOM. | ||
customElements.define = function (tagName, Ctr) { | ||
Ctr[Symbol.for('tagName')] = tagName; | ||
return ceDefine.call(this, tagName, Ctr); | ||
return litCeDefine.call(this, tagName, Ctr); | ||
}; |
import './server-shim.js'; | ||
import '@lit-labs/ssr/lib/render-lit-html.js'; | ||
import { LitElementRenderer } from '@lit-labs/ssr/lib/lit-element-renderer.js'; | ||
@@ -21,6 +20,6 @@ import * as parse5 from 'parse5'; | ||
const Ctr = getCustomElementConstructor(Component); | ||
return !!(Ctr && Ctr._$litElement$); | ||
return !!Ctr?._$litElement$; | ||
} | ||
async function check(Component, _props, _children) { | ||
async function check(Component) { | ||
// Lit doesn't support getting a tagName from a Constructor at this time. | ||
@@ -64,3 +63,8 @@ // So this must be a string at the moment. | ||
yield `>`; | ||
const shadowContents = instance.renderShadow({}); | ||
const shadowContents = instance.renderShadow({ | ||
elementRenderers: [LitElementRenderer], | ||
customElementInstanceStack: [instance], | ||
customElementHostStack: [instance], | ||
deferHydration: false, | ||
}); | ||
if (shadowContents !== undefined) { | ||
@@ -67,0 +71,0 @@ const { mode = 'open', delegatesFocus } = instance.shadowRootOptions ?? {}; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
158
0
22579
6
12
338
+ Added@lit-labs/ssr-client@^1.1.5
+ Added@lit-labs/ssr@3.2.2(transitive)
+ Added@parse5/tools@0.3.0(transitive)
+ Added@webcomponents/template-shadowroot@0.2.1(transitive)
- Removed@lit-labs/ssr@2.3.0(transitive)
- Removed@lit/reactive-element@1.6.3(transitive)
- Removed@parse5/tools@0.1.0(transitive)
- Removed@webcomponents/template-shadowroot@0.1.0(transitive)
- Removedlit@2.8.0(transitive)
- Removedlit-element@3.3.3(transitive)
- Removedlit-html@2.8.0(transitive)
Updated@lit-labs/ssr@^3.2.0