Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@kyubisation
Copy link
Contributor

@kyubisation kyubisation commented Dec 20, 2024

This PR adds a shim for CSSStyleSheet (and associated classes) and a CSS loader hook for Node.js.

Limitation
The CSS loader cannot be registered synchronously (i.e. if you import LitElement/the shim and a .css file from the same file, it will break). Due to this the loader needs to be registered via --import @lit-labs/ssr-dom-shim/css-loader.js via Node.js CLI or imported before dynamically importing components.

Closes #4862
Relates to #2631

@changeset-bot
Copy link

changeset-bot bot commented Dec 20, 2024

🦋 Changeset detected

Latest commit: 2ab5121

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@lit-labs/ssr-dom-shim Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@justinfagnani
Copy link
Collaborator

Limitation The CSS loader cannot be registered synchronously

This seems expected. We can't rely on import ordering because while eval happens in order, fetching and parsing happen in parallel.

To discuss

  • Should CSSStyleSheet be added to the global context?

Not by default, it should be installed with the other DOM globals.

  • How to proceed with the loader?
  • Should the logic in packages/reactive-element/src/css-tag.ts be adapted?

What do you mean with these last two points?

@kyubisation
Copy link
Contributor Author

  • How to proceed with the loader?

How to provide/integrate the loader. I think you answered this by suggesting to add it to install-global-dom-shim.ts.

  • Should the logic in packages/reactive-element/src/css-tag.ts be adapted?

Should usage of CSSStyleSheet be enabled in SSR?

@kyubisation
Copy link
Contributor Author

I changed the terminology from loader to hook to align with the terminology used by Node.js

@kyubisation kyubisation marked this pull request as ready for review December 31, 2024 16:54
@kyubisation
Copy link
Contributor Author

Hello @thescientist13
Can you check whether this PR meets the criteria to close #4862?
I have the thought to create a follow-up PR to add an entry/import module @lit-labs/ssr/dom-shim.js, which would install the hook and the DOM shim globals. It could be used like node --import @lit-labs/ssr/dom-shim.js my-script.js. Would that help for your use case?

@thescientist13
Copy link
Contributor

thescientist13 commented Jan 6, 2025

Hey @kyubisation thanks so much for all your great work on this!

Can you check whether this PR meets the criteria to close #4862?

It seems like it would, but I haven't had a case to use the installWindowOnGlobal yet in a Lit+SSR project so my experience / usage there is limited.

Inferring from the changes in this PR though, would I just simply need to add these lines to the top of my script in the repro repo?

// add these lines
import '@lit-labs/ssr-dom-shim/css-hook.js';
import {installWindowOnGlobal} from './dom-shim.js';
installWindowOnGlobal();

// rest of the code as normal
import fs from 'node:fs/promises';
import { html } from 'lit';
import { render } from '@lit-labs/ssr';
import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
import './components/greeting/greeting.js';

//...

I have the thought to create a follow-up PR to add an entry/import module @lit-labs/ssr/dom-shim.js, which would install the hook and the DOM shim globals. It could be used like node --import @lit-labs/ssr/dom-shim.js my-script.js. Would that help for your use case?

Yeah, I think that would be helpful for composition purposes, so consumers can cherry-pick whatever parts they want of this implementation, which I think is really nice for folks building meta-frameworks around Lit / Lit+SSR.


Left some other thoughts in the PR, feel free to take or leave them.

"types": "./index.d.ts",
"default": "./index.js"
},
"./css-hook.js": {
Copy link
Contributor

@thescientist13 thescientist13 Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a heads up that there is an option to set an export condition
https://nodejs.org/api/module.html#enabling

Where some-package has an "exports" field defining the /register export to map to a file that calls register(), like the following register-hooks.js example.

edit: though maybe this is what you indicated would be the follow up PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit: though maybe this is what you indicated would be the follow up PR?

Yes, basically. But to be able to use it from @lit-labs/ssr I already need a specific exports entry in @lit-labs/ssr-dom-shim. This also allows it to be used directly from this package, if so desired.

@kyubisation
Copy link
Contributor Author

Inferring from the changes in this PR though, would I just simply need to add these lines to the top of my script in the repro repo?

// add these lines
import '@lit-labs/ssr-dom-shim/css-hook.js';
import {installWindowOnGlobal} from './dom-shim.js';
installWindowOnGlobal();

// rest of the code as normal
import fs from 'node:fs/promises';
import { html } from 'lit';
import { render } from '@lit-labs/ssr';
import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
import './components/greeting/greeting.js';

//...

No, that would still break, as the imports to the hook and the component (which in turn imports the css file) are on the same "level".
You would either to dynamically import the/any component (e.g. await import('./components/greeting/greeting.js');) or register the hook via Node.js CLI/environment variable paramters (e.g. node --import @lit-labs/ssr-dom-shim/css-hook.js my-script.js, which I think you already adapted here).

@thescientist13
Copy link
Contributor

thescientist13 commented Jan 16, 2025

No, that would still break, as the imports to the hook and the component (which in turn imports the css file) are on the same "level".
You would either to dynamically import the/any component (e.g. await import('./components/greeting/greeting.js');) or register the hook via Node.js CLI/environment variable paramters (e.g. node --import @lit-labs/ssr-dom-shim/css-hook.js my-script.js, which I think you already adapted here).

Ah, OK. I'm reviewing the README a bit with more your recommendations and think I get it now.

I assume this is because of the requirement to exclude CSSStyleSheet from being auto-installed? I suppose if that was not the case, we wouldn't have to "externalize" this to userland through something like installWindowOnGlobal? Would certainly like to see if we can discuss this a bit during the next eng call. Maybe we could change the position on this once (CSS) Import Attributes reach full interop? 🤞

@kyubisation kyubisation changed the title [@lit-labs/ssr-dom-shim] Implement limited shim for CSSStyleSheet and CSS loader for Node.js [labs/ssr-dom-shim] Implement limited shim for CSSStyleSheet and CSS loader for Node.js Jan 30, 2025
@kyubisation
Copy link
Contributor Author

@justinfagnani @thescientist13 I implemented a check whether the runtime environment support importing CSS files directly and whether hooks can be registered. Feel free to provide feedback, if you have concerns.

Copy link
Contributor

@thescientist13 thescientist13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to test this out when it is ready / published 👍

@justinfagnani justinfagnani merged commit 5057fee into lit:main Aug 20, 2025
7 checks passed
@kyubisation kyubisation deleted the feat-dom-shim-cssstylesheet branch November 21, 2025 23:35
@lit-robot lit-robot mentioned this pull request Dec 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[labs/ssr] expose minimal CSSStyleSheet class in SSR DOM Shim

3 participants