Skip to content

Conversation

@bennypowers
Copy link
Owner

@bennypowers bennypowers commented Nov 3, 2025

Summary by CodeRabbit

  • New Features

    • Released vite-plugin-lit-css v1.0.0 — import CSS as tagged template literals with Vite 4/5/6 support, preprocessor support, minification, and HMR.
  • Documentation

    • Added comprehensive plugin README, changelog, and integration-test guide with usage examples and configuration samples.
  • Tests

    • Added integration test project, dev/build test harness, example component, and expected output fixtures to validate transforms.
  • Chores

    • Added package manifest and added a README link to the Vite plugin; updated ESLint ignore.

@changeset-bot
Copy link

changeset-bot bot commented Nov 3, 2025

🦋 Changeset detected

Latest commit: cc8320c

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

This PR includes changesets to release 1 package
Name Type
vite-plugin-lit-css 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

@bennypowers
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

Walkthrough

A new package vite-plugin-lit-css was added with a Vite plugin implementation, package metadata, docs, changelog, integration tests, unit tests/fixtures, ESLint ignore update, and a top-level README entry listing Vite.

Changes

Cohort / File(s) Summary
Root README Update
README.md
Added a Vite plugin entry link to the list of integration packages.
Plugin Package Manifest
packages/vite-plugin-lit-css/package.json
New npm package manifest declaring package metadata, dependencies, peerDependencies and exports for vite-plugin-lit-css.
Core Plugin Implementation
packages/vite-plugin-lit-css/vite-plugin-lit-css.ts
New Vite plugin implementation exporting litCSS and LitCSSOptions; implements resolveId and load to provide virtual .lit-css.js modules and run the @pwrs/lit-css transform (emits transformed JS and source map, handles errors).
Documentation & Release Notes
packages/vite-plugin-lit-css/README.md, packages/vite-plugin-lit-css/CHANGELOG.md, .changeset/vite-plugin-lit-css.md
Added package README with usage, options and examples; CHANGELOG entry for v1.0.0; and a changeset describing the plugin and supported features (HMR, transforms, preprocessors).
Integration Test Harness
packages/vite-plugin-lit-css/integration-test/package.json, packages/vite-plugin-lit-css/integration-test/vite.config.js, packages/vite-plugin-lit-css/integration-test/index.html, packages/vite-plugin-lit-css/integration-test/README.md, packages/vite-plugin-lit-css/integration-test/src/*
New integration-test project: package.json, Vite config registering the plugin, dev/build scripts, HTML test page, LitElement component (src/my-element.js), stylesheet (src/styles.css), and README documenting how to run and verify the integration test.
Unit Tests & Fixtures
packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js, packages/vite-plugin-lit-css/test/expected/*
Added test harness and expected output fixtures covering bare imports, basic transforms, FAST integration, PostCSS/SCSS, special characters and minified output.
ESLint Ignore Update
.eslintignore
Added pattern packages/*/integration-test/**/*.js to ignore integration-test JS files.

Sequence Diagram(s)

sequenceDiagram
    participant Vite as Vite (resolver & bundler)
    participant Plugin as vite-plugin-lit-css
    participant FS as File System
    participant LitCSS as @pwrs/lit-css

    Vite->>Plugin: resolveId(importer -> "styles.css")
    Plugin->>Plugin: apply include/exclude filter
    alt matches filter
        Plugin-->>Vite: return virtual id "styles.css.lit-css.js"
        Vite->>Plugin: load("styles.css.lit-css.js")
        Plugin->>FS: read "styles.css"
        FS-->>Plugin: CSS content
        Plugin->>LitCSS: transform(css, options)
        LitCSS-->>Plugin: JS module (tagged template)
        Plugin-->>Vite: return transformed JS + source map
    else not matched
        Plugin-->>Vite: return undefined (no handling)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas needing focused review:
    • packages/vite-plugin-lit-css/vite-plugin-lit-css.ts — filter logic, resolveId/load behavior, virtual id scheme, error emission, source-map handling.
    • Integration-test config and scripts — integration-test/vite.config.js, integration-test/package.json, and index.html wiring.
    • Test fixtures in test/expected/* — verify representative outputs (special chars, minified, preprocessors).

Poem

🐰 A new plugin hops into the nest,
CSS to templates, snugly dressed,
Docs and tests in tidy stacks,
HMR humming on development tracks,
I nibble code and then I rest.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The pull request title "feat(vite): add vite support" is related to the changeset since the PR does introduce Vite support through a new vite-plugin-lit-css package. However, the title is vague and overly broad. While the scope "(vite)" provides some context, the phrase "add vite support" doesn't clearly convey the specific change: introducing a new Vite plugin that enables importing CSS files as Lit tagged template literals. A teammate scanning the commit history would have difficulty understanding what was actually implemented without reading the full changeset summary. The title could be more specific and informative. Consider revising the title to be more specific about what Vite support is being added. A clearer title might be "feat: add vite-plugin-lit-css for importing CSS as Lit template literals" or "feat(vite): introduce vite-plugin-lit-css" to help reviewers and future readers understand the primary change at a glance without needing to examine the full changeset.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/vite

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2340d36 and cc8320c.

📒 Files selected for processing (8)
  • packages/vite-plugin-lit-css/test/expected/bare/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/boop.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/fast.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/uglified.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/postcss/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/scss/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/special-chars/output.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/vite-plugin-lit-css/test/expected/bare/output.js
  • packages/vite-plugin-lit-css/test/expected/basic/output.js
  • packages/vite-plugin-lit-css/test/expected/basic/fast.js
  • packages/vite-plugin-lit-css/test/expected/basic/uglified.js
  • packages/vite-plugin-lit-css/test/expected/basic/boop.js
  • packages/vite-plugin-lit-css/test/expected/special-chars/output.js
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: bennypowers
Repo: bennypowers/lit-css PR: 70
File: packages/vite-plugin-lit-css/integration-test/src/my-element.js:5-5
Timestamp: 2025-11-03T06:29:44.714Z
Learning: In the bennypowers/lit-css repository, the .eslintignore file contains the pattern "packages/*/integration-test/**/*.js" which correctly excludes integration test files from linting, so ESLint parsing errors should not occur for files in integration-test directories.
📚 Learning: 2025-11-03T06:29:44.714Z
Learnt from: bennypowers
Repo: bennypowers/lit-css PR: 70
File: packages/vite-plugin-lit-css/integration-test/src/my-element.js:5-5
Timestamp: 2025-11-03T06:29:44.714Z
Learning: In the bennypowers/lit-css repository, the .eslintignore file contains the pattern "packages/*/integration-test/**/*.js" which correctly excludes integration test files from linting, so ESLint parsing errors should not occur for files in integration-test directories.

Applied to files:

  • packages/vite-plugin-lit-css/test/expected/postcss/output.js
🧬 Code graph analysis (2)
packages/vite-plugin-lit-css/test/expected/scss/output.js (3)
packages/vite-plugin-lit-css/test/expected/bare/output.js (1)
  • styles (2-5)
packages/vite-plugin-lit-css/test/expected/basic/output.js (1)
  • styles (2-5)
packages/vite-plugin-lit-css/test/expected/basic/uglified.js (1)
  • styles (2-2)
packages/vite-plugin-lit-css/test/expected/postcss/output.js (4)
packages/vite-plugin-lit-css/test/expected/bare/output.js (1)
  • styles (2-5)
packages/vite-plugin-lit-css/test/expected/basic/output.js (1)
  • styles (2-5)
packages/vite-plugin-lit-css/test/expected/basic/uglified.js (1)
  • styles (2-2)
packages/vite-plugin-lit-css/test/expected/scss/output.js (1)
  • styles (2-2)
🔇 Additional comments (2)
packages/vite-plugin-lit-css/test/expected/scss/output.js (1)

1-6: LGTM! Expected output fixture is correctly structured.

This test expected output follows the established pattern used across the test suite: importing css from lit, defining minified styles, and exporting both as default and named exports. The structure is consistent with other expected outputs like bare/output.js and basic/uglified.js.

packages/vite-plugin-lit-css/test/expected/postcss/output.js (1)

1-6: LGTM! PostCSS expected output is correctly structured.

This test fixture correctly represents the expected PostCSS transformation output with minified CSS rules. The dual-export pattern and structure align with other expected outputs in the test suite.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (3)
packages/vite-plugin-lit-css/CHANGELOG.md (1)

3-3: Consider adding a release date to the version header.

Following "Keep a Changelog" conventions, include the release date in the format [1.0.0] - YYYY-MM-DD to provide clarity on when this version was released. This is particularly useful for tracking release timelines and is a common practice across many open-source projects.

Example:

-## 1.0.0
+## [1.0.0] - 2025-11-03
packages/vite-plugin-lit-css/README.md (1)

1-170: Excellent documentation!

The README is comprehensive and well-structured, covering installation, configuration, usage examples for multiple scenarios (Lit, FAST, Sass, PostCSS), and includes helpful notes about HMR and how the plugin works.

If you'd like to address the style suggestion from the linter, consider this minor change:

-This plugin works seamlessly with Vite's HMR. When you modify a CSS file, Vite will automatically reload the module and update your component styles without a full page refresh.
+This plugin works seamlessly with Vite's HMR. When you modify a CSS file, Vite will automatically reload the module and update your component styles without a full-page refresh.
packages/vite-plugin-lit-css/vite-plugin-lit-css.ts (1)

41-70: Robust resolveId implementation with good delegation pattern.

The implementation correctly:

  • Performs early returns for non-applicable cases
  • Delegates to other plugins via this.resolve with skipSelf
  • Uses the filter on the resolved path (not the raw import)
  • Returns a virtual module ID with the \0 prefix convention

The static analysis warning about string concatenation on line 66 is a false positive—this is the standard Rollup convention for virtual modules.

You may optionally address the linter's formatting suggestions:

       const resolution = await this.resolve(source, importer, {
-        skipSelf: true,  // Don't call ourselves recursively
+        skipSelf: true, // Don't call ourselves recursively
         ...options,
       });
       if (!source.endsWith('.css') && !source.endsWith('.scss') && !source.endsWith('.sass') &&
-          !source.endsWith('.less') && !source.endsWith('.styl')) {
+          !source.endsWith('.less') && !source.endsWith('.styl'))
         return null;
-      }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c69d07 and 6f7f563.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/vite-plugin-lit-css/integration-test/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (20)
  • README.md (1 hunks)
  • packages/vite-plugin-lit-css/CHANGELOG.md (1 hunks)
  • packages/vite-plugin-lit-css/README.md (1 hunks)
  • packages/vite-plugin-lit-css/integration-test/README.md (1 hunks)
  • packages/vite-plugin-lit-css/integration-test/index.html (1 hunks)
  • packages/vite-plugin-lit-css/integration-test/package.json (1 hunks)
  • packages/vite-plugin-lit-css/integration-test/src/my-element.js (1 hunks)
  • packages/vite-plugin-lit-css/integration-test/src/styles.css (1 hunks)
  • packages/vite-plugin-lit-css/integration-test/vite.config.js (1 hunks)
  • packages/vite-plugin-lit-css/package.json (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/bare/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/boop.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/fast.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/basic/uglified.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/postcss/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/scss/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/expected/special-chars/output.js (1 hunks)
  • packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js (1 hunks)
  • packages/vite-plugin-lit-css/vite-plugin-lit-css.ts (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Verify PR
packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js

[warning] 2-2: eslint: 'aliasPlugin' is defined but never used. (no-unused-vars). Command: eslint .


[error] 55-55: eslint: Unnecessary { after 'if' condition. (curly). Command: eslint .

packages/vite-plugin-lit-css/integration-test/src/my-element.js

[error] 5-5: eslint: Parsing error: Unexpected token =. Command: eslint .

🪛 GitHub Check: verify
packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js

[failure] 61-61:
Unnecessary { after 'if' condition


[failure] 55-55:
Unnecessary { after 'if' condition


[warning] 2-2:
'aliasPlugin' is defined but never used

packages/vite-plugin-lit-css/vite-plugin-lit-css.ts

[warning] 86-86:
Unexpected any. Specify a different type


[failure] 66-66:
Unexpected string concatenation


[failure] 55-55:
Multiple spaces found before '// Don't call ...'


[failure] 48-48:
Unnecessary { after 'if' condition

🪛 LanguageTool
packages/vite-plugin-lit-css/README.md

[uncategorized] ~155-~155: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... update your component styles without a full page refresh. ## How It Works This plugin ...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🔇 Additional comments (22)
README.md (1)

30-30: LGTM!

The addition of Vite to the supported tools list is consistent with the existing format and correctly links to the new package directory.

packages/vite-plugin-lit-css/test/expected/basic/uglified.js (1)

1-5: LGTM!

This test fixture correctly demonstrates the expected output for minified CSS transformation, with proper dual export pattern (default and named).

packages/vite-plugin-lit-css/test/expected/basic/fast.js (1)

1-8: LGTM!

This test fixture correctly demonstrates the expected output for FAST element integration, importing from the correct package and using the standard export pattern.

packages/vite-plugin-lit-css/test/expected/basic/boop.js (1)

1-8: LGTM!

This test fixture correctly validates the custom specifier and tag functionality, demonstrating that the plugin can work with arbitrary template tag functions beyond just css from lit.

packages/vite-plugin-lit-css/package.json (1)

1-40: LGTM!

The package manifest is well-configured with:

  • Proper dual package support (ESM + CJS) via the exports field
  • Appropriate peer dependency range covering Vite 4.x, 5.x, and 6.x
  • Correct dependencies for the plugin functionality
  • Properly scoped files array for publication
packages/vite-plugin-lit-css/vite-plugin-lit-css.ts (3)

8-18: LGTM!

The LitCSSOptions interface is well-defined with clear JSDoc comments and appropriate type constraints.


26-40: LGTM!

The plugin initialization logic correctly destructures options with sensible defaults and creates a Rollup filter for file matching. The enforce: 'pre' configuration appropriately prioritizes this plugin before Vite's built-in CSS handling.


93-93: LGTM!

The default export provides convenient import syntax while the named export remains available for explicit imports.

packages/vite-plugin-lit-css/integration-test/vite.config.js (1)

1-18: LGTM!

The integration test configuration is well-structured:

  • Correctly imports the plugin from the parent directory
  • Uses library build mode appropriate for testing a component
  • Properly externalizes lit to avoid bundling peer dependencies
packages/vite-plugin-lit-css/integration-test/src/styles.css (1)

1-9: LGTM! Clean test fixture.

The CSS is simple and appropriate for integration testing. The hotpink color provides clear visual verification that the plugin is working correctly.

packages/vite-plugin-lit-css/test/expected/scss/output.js (1)

1-5: LGTM! Consistent test fixture pattern.

The expected output follows the standard pattern used across all test fixtures in this PR.

packages/vite-plugin-lit-css/test/expected/basic/output.js (1)

1-8: LGTM! Consistent test fixture pattern.

The expected output follows the standard pattern used across all test fixtures in this PR.

packages/vite-plugin-lit-css/test/expected/bare/output.js (1)

1-8: LGTM! Consistent test fixture pattern.

The expected output follows the standard pattern used across all test fixtures in this PR.

packages/vite-plugin-lit-css/integration-test/index.html (1)

1-16: LGTM! Well-structured integration test page.

The HTML provides a clear test harness with visual verification instructions. The structure is appropriate for Vite dev server testing.

packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js (1)

15-18: LGTM! Good type-checking practice.

The type check for the plugin configuration is a nice touch to ensure TypeScript types are correct.

packages/vite-plugin-lit-css/test/expected/postcss/output.js (1)

1-5: LGTM! Consistent test fixture pattern.

The expected output follows the standard pattern used across all test fixtures in this PR. The concatenated CSS rules appropriately demonstrate PostCSS processing.

packages/vite-plugin-lit-css/integration-test/README.md (1)

1-40: LGTM! Excellent documentation.

The README provides comprehensive guidance on the integration test purpose, usage, and verification steps. The rationale for having integration tests alongside unit tests is particularly valuable.

packages/vite-plugin-lit-css/integration-test/src/my-element.js (3)

7-12: LGTM!

The render method is correctly implemented and provides clear visual feedback for integration testing.


15-15: LGTM!

The custom element registration follows web components best practices with a properly formatted kebab-case name.


1-2: Verify the CSS import transformation.

The component imports styles from a CSS file without importing css from 'lit'. The plugin should transform the CSS import to return a properly wrapped Lit css template literal. Ensure the plugin handles this transformation correctly in both dev and build modes.

Run the following script to verify the plugin transformation:

packages/vite-plugin-lit-css/integration-test/package.json (1)

1-15: LGTM!

The package manifest is well-structured for an integration test with appropriate dependencies and scripts. The version ranges for lit (^3.0.0) and vite (^5.0.0) are current, and marking the package as private is correct.

packages/vite-plugin-lit-css/test/expected/special-chars/output.js (1)

1-11: LGTM!

This test fixture correctly demonstrates the expected plugin output for special character handling (including the emoji in the comment) and validates the dual export pattern that supports both default and named imports.

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.

2 participants