diff --git a/.changeset/vite-plugin-lit-css.md b/.changeset/vite-plugin-lit-css.md
new file mode 100644
index 0000000..c6eb65d
--- /dev/null
+++ b/.changeset/vite-plugin-lit-css.md
@@ -0,0 +1,14 @@
+---
+"vite-plugin-lit-css": minor
+---
+
+Add Vite plugin for importing CSS files as Lit tagged template literals
+
+This new package provides a Vite plugin that transforms CSS imports into Lit's `css` tagged template literals, enabling seamless CSS-in-JS workflow for Lit components in Vite projects.
+
+Features:
+- Works with both Vite dev server and build modes
+- Supports virtual module system for proper module resolution
+- Handles bare specifiers, relative paths, and aliases via Vite's resolution system
+- Compatible with multiple CSS preprocessor extensions (`.css`, `.scss`, `.sass`, `.less`, `.styl`)
+- Leverages the core `@pwrs/lit-css` transform library
diff --git a/README.md b/README.md
index c1ad399..0a97b84 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,8 @@ In the mean time, enjoy importing your CSS into your component files.
- [Shared Logic](./packages/lit-css)
- [esbuild](./packages/esbuild-plugin-lit-css)
-- [Webpack](./packages/lit-css-loader)
+- [TypeScript](./packages/typescript-transform-lit-css)
- [Rollup](./packages/rollup-plugin-lit-css)
+- [Webpack](./packages/lit-css-loader)
+- [Vite](./packages/vite-plugin-lit-css)
- [Parcel](./packages/parcel-transformer-lit-css)
-- [TypeScript](./packages/typescript-transform-lit-css)
diff --git a/package-lock.json b/package-lock.json
index eecf8c8..2596d84 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2605,7 +2605,7 @@
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -2627,7 +2627,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -2637,7 +2637,7 @@
"version": "0.3.11",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -2648,14 +2648,14 @@
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.31",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -5235,7 +5235,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5249,7 +5248,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5263,7 +5261,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5277,7 +5274,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5291,7 +5287,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5305,7 +5300,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5319,7 +5313,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5333,7 +5326,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5347,7 +5339,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5361,7 +5352,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5375,7 +5365,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5389,7 +5378,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5403,7 +5391,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5417,7 +5404,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5431,7 +5417,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5445,7 +5430,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5459,7 +5443,6 @@
"cpu": [
"s390x"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5473,7 +5456,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5487,7 +5469,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5501,7 +5482,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5515,7 +5495,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5529,7 +5508,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5543,7 +5521,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5557,7 +5534,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -5571,7 +5547,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -6669,7 +6644,7 @@
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -7240,7 +7215,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/buffer-shims": {
@@ -7413,7 +7388,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
@@ -9678,6 +9653,24 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
"node_modules/figures": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
@@ -9845,7 +9838,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@@ -10584,7 +10576,7 @@
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/import-fresh": {
@@ -11486,7 +11478,6 @@
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
- "dev": true,
"license": "MIT",
"optional": true,
"bin": {
@@ -11779,7 +11770,7 @@
"version": "1.31.1",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz",
"integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==",
- "dev": true,
+ "devOptional": true,
"license": "MPL-2.0",
"dependencies": {
"detect-libc": "^2.0.3"
@@ -12040,7 +12031,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
"engines": {
"node": ">=8"
@@ -14463,7 +14454,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
@@ -14790,7 +14781,6 @@
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
@@ -14986,7 +14976,7 @@
"version": "1.97.3",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz",
"integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
@@ -15301,7 +15291,7 @@
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
@@ -16032,7 +16022,7 @@
"version": "5.46.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz",
"integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
- "dev": true,
+ "devOptional": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -16179,6 +16169,23 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -16705,6 +16712,85 @@
"node": ">= 0.8"
}
},
+ "node_modules/vite": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
+ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-lit-css": {
+ "resolved": "packages/vite-plugin-lit-css",
+ "link": true
+ },
"node_modules/vscode-json-languageservice": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz",
@@ -17398,6 +17484,17 @@
"typescript": "^5"
}
},
+ "packages/vite-plugin-lit-css": {
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@pwrs/lit-css": "^4.0.0",
+ "@rollup/pluginutils": "^5.1.4"
+ },
+ "peerDependencies": {
+ "vite": "^4.0.0 || ^5.0.0 || ^6.0.0"
+ }
+ },
"packages/web-dev-server-plugin-lit-css": {
"version": "4.0.0",
"license": "ISC",
diff --git a/packages/vite-plugin-lit-css/CHANGELOG.md b/packages/vite-plugin-lit-css/CHANGELOG.md
new file mode 100644
index 0000000..ee77454
--- /dev/null
+++ b/packages/vite-plugin-lit-css/CHANGELOG.md
@@ -0,0 +1,12 @@
+# vite-plugin-lit-css
+
+## 1.0.0
+
+### Major Changes
+
+- Initial release of Vite plugin for lit-css
+- Support for importing CSS files as tagged template literals
+- Compatible with Vite 4.x, 5.x, and 6.x
+- Full support for custom transforms (Sass, PostCSS, etc.)
+- Minification support via cssnano
+- Hot Module Replacement (HMR) support
diff --git a/packages/vite-plugin-lit-css/README.md b/packages/vite-plugin-lit-css/README.md
new file mode 100644
index 0000000..2188927
--- /dev/null
+++ b/packages/vite-plugin-lit-css/README.md
@@ -0,0 +1,171 @@
+# vite-plugin-lit-css
+
+Vite plugin to import CSS files as JavaScript tagged-template literal objects.
+
+> _The "Lit" stands for "Literal"_
+
+You can use it to import CSS for various libraries like `lit`, `@microsoft/fast-element`, or others.
+
+## Do I Need This?
+
+No. This is an optional package whose sole purpose is to make it easier to write CSS-in-CSS while working on lit-element projects. You can just as easily write your CSS in some '`styles.css.js`' modules a la:
+
+```js
+import { css } from 'lit';
+export default css`:host { display: block; }`;
+```
+
+And this may actually be preferred.
+
+Hopefully this package will become quickly obsolete when the [CSS Modules Proposal](https://github.com/w3c/webcomponents/issues/759) (or something like it) is accepted and implemented.
+
+In the mean time, enjoy importing your CSS into your component files.
+
+## Options
+
+| Name | Accepts | Default |
+| ----------- | ----------------------------------------------------------------------------- | -------------- |
+| `include` | Array of glob of files to include. | `['**/*.css']` |
+| `exclude` | Array of glob of files to exclude. | `undefined` |
+| `cssnano` | Boolean or Object of [cssnano][nanoopts] options. | `false` |
+| `specifier` | Package to import `css` from | `lit` |
+| `tag` | Name of the template-tag function | `css` |
+| `transform` | Optional function (sync or async) which transforms css sources (e.g. postcss) | `x => x` |
+
+## Installation
+
+```bash
+npm install --save-dev vite-plugin-lit-css
+```
+
+## Usage
+
+```js
+// vite.config.js
+import { defineConfig } from 'vite';
+import litCSS from 'vite-plugin-lit-css';
+
+export default defineConfig({
+ plugins: [
+ litCSS({ include: '**/*.css', cssnano: true })
+ ]
+});
+```
+
+Then import your CSS:
+
+```css
+:host {
+ display: block;
+}
+
+h1 {
+ color: hotpink;
+}
+```
+
+```ts
+import { LitElement, html } from 'lit';
+import { customElement } from 'lit/decorators.js';
+
+import style from './css-in-css.css';
+
+@customElement('css-in-css')
+class CSSInCSS extends LitElement {
+ static readonly styles = [style];
+
+ render() {
+ return html`
It's Lit!
`;
+ }
+}
+```
+
+### Usage with FAST
+
+```js
+// vite.config.js
+import { defineConfig } from 'vite';
+import litCSS from 'vite-plugin-lit-css';
+
+export default defineConfig({
+ plugins: [
+ litCSS({ specifier: '@microsoft/fast-element' })
+ ]
+});
+```
+
+```ts
+import { FASTElement, customElement, html } from '@microsoft/fast-element';
+
+import styles from './css-in-css.css';
+
+const template = html`It's Lit!
`;
+
+@customElement({ name: 'css-in-css', template, styles })
+class CSSinCSS extends FASTElement {}
+```
+
+### Usage with Sass, Less, PostCSS, etc.
+
+To load scss files:
+
+1. Specify an `include` option which includes scss files (i.e. a glob or regexp)
+2. Define a `transform` function in the plugin options.
+
+```js
+// vite.config.js
+import { defineConfig } from 'vite';
+import litCSS from 'vite-plugin-lit-css';
+import Sass from 'sass';
+
+export default defineConfig({
+ plugins: [
+ litCSS({
+ include: '**/*.scss',
+ transform: (data, { filePath }) =>
+ Sass.compile(filePath).css,
+ })
+ ]
+});
+```
+
+Similarly, to transform sources using PostCSS, specify a `transform` function:
+
+```js
+// vite.config.js
+import { defineConfig } from 'vite';
+import litCSS from 'vite-plugin-lit-css';
+import postcss from 'postcss';
+import postcssNesting from 'postcss-nesting';
+
+const processor = postcss(postcssNesting());
+
+export default defineConfig({
+ plugins: [
+ litCSS({
+ transform: (css, { filePath }) =>
+ processor.process(css, { from: filePath }).css,
+ })
+ ]
+});
+```
+
+## Hot Module Replacement (HMR)
+
+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.
+
+## How It Works
+
+This plugin uses Vite's `load` hook with `enforce: 'pre'` to intercept CSS imports before Vite's built-in CSS handling. Since Vite plugins are Rollup plugins under the hood, this plugin works with Vite's build process.
+
+**Note:** This plugin is designed to transform CSS files into JavaScript tagged template literals. If you experience conflicts with Vite's built-in CSS handling in development mode, you may need to adjust your Vite configuration. The plugin has been tested primarily with production builds. For development server and Vitest usage, please test in your specific environment and report any issues.
+
+## Other Plugins
+
+Looking for other build tools?
+- Webpack: [lit-css-loader](../lit-css-loader)
+- esbuild: [esbuild-plugin-lit-css](../esbuild-plugin-lit-css)
+- Rollup: [rollup-plugin-lit-css](../rollup-plugin-lit-css)
+- TypeScript: [typescript-transform-lit-css](../typescript-transform-lit-css)
+
+[nanoopts]: https://cssnano.co/docs/config-file/#configuration-options
diff --git a/packages/vite-plugin-lit-css/integration-test/README.md b/packages/vite-plugin-lit-css/integration-test/README.md
new file mode 100644
index 0000000..59b4f55
--- /dev/null
+++ b/packages/vite-plugin-lit-css/integration-test/README.md
@@ -0,0 +1,40 @@
+# Vite Plugin Integration Test
+
+This directory contains an integration test that verifies the vite-plugin-lit-css works correctly with real Vite builds.
+
+## Purpose
+
+This integration test serves as proof that the plugin:
+- Correctly transforms CSS imports into Lit's `css` tagged template literals
+- Works with Vite's build process
+- Handles the virtual module system properly
+- Produces valid bundled output
+
+## Running the Integration Test
+
+### Build Mode
+
+```bash
+npm run build
+```
+
+This will build the test application and output to `dist/my-element.js`.
+
+### Dev Server Mode
+
+```bash
+npm run dev
+```
+
+This will start the Vite dev server at `http://localhost:5173/`. Open the URL in your browser to see the component rendered with the transformed CSS.
+
+## Verification
+
+After building, check that:
+1. The build completes without errors
+2. The output file `dist/my-element.js` contains the CSS imported from `styles.css` as a `css` tagged template literal
+3. The styles are properly assigned to the component's `static styles` property
+
+## Why an Integration Test?
+
+The plugin uses Vite's virtual module system with custom resolution logic. An integration test with actual Vite builds provides confidence that the plugin works in real-world scenarios, complementing the unit tests.
diff --git a/packages/vite-plugin-lit-css/integration-test/index.html b/packages/vite-plugin-lit-css/integration-test/index.html
new file mode 100644
index 0000000..83a0a15
--- /dev/null
+++ b/packages/vite-plugin-lit-css/integration-test/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Vite Plugin lit-css Dev Server Test
+
+
+ Vite Plugin lit-css - Dev Server Test
+ If the text below is styled with hotpink, the plugin works in dev mode!
+
+
+
+
+
+
diff --git a/packages/vite-plugin-lit-css/integration-test/package-lock.json b/packages/vite-plugin-lit-css/integration-test/package-lock.json
new file mode 100644
index 0000000..245ff3b
--- /dev/null
+++ b/packages/vite-plugin-lit-css/integration-test/package-lock.json
@@ -0,0 +1,995 @@
+{
+ "name": "vite-plugin-lit-css-integration-test",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "vite-plugin-lit-css-integration-test",
+ "dependencies": {
+ "lit": "^3.0.0"
+ },
+ "devDependencies": {
+ "vite": "^5.0.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@lit-labs/ssr-dom-shim": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.4.0.tgz",
+ "integrity": "sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@lit/reactive-element": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.1.tgz",
+ "integrity": "sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.4.0"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz",
+ "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz",
+ "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz",
+ "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz",
+ "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz",
+ "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz",
+ "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz",
+ "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz",
+ "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz",
+ "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz",
+ "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz",
+ "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz",
+ "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz",
+ "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz",
+ "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz",
+ "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
+ "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz",
+ "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz",
+ "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz",
+ "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz",
+ "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz",
+ "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz",
+ "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/lit": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.1.tgz",
+ "integrity": "sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit/reactive-element": "^2.1.0",
+ "lit-element": "^4.2.0",
+ "lit-html": "^3.3.0"
+ }
+ },
+ "node_modules/lit-element": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.1.tgz",
+ "integrity": "sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.4.0",
+ "@lit/reactive-element": "^2.1.0",
+ "lit-html": "^3.3.0"
+ }
+ },
+ "node_modules/lit-html": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.1.tgz",
+ "integrity": "sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.52.5",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz",
+ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.52.5",
+ "@rollup/rollup-android-arm64": "4.52.5",
+ "@rollup/rollup-darwin-arm64": "4.52.5",
+ "@rollup/rollup-darwin-x64": "4.52.5",
+ "@rollup/rollup-freebsd-arm64": "4.52.5",
+ "@rollup/rollup-freebsd-x64": "4.52.5",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.52.5",
+ "@rollup/rollup-linux-arm-musleabihf": "4.52.5",
+ "@rollup/rollup-linux-arm64-gnu": "4.52.5",
+ "@rollup/rollup-linux-arm64-musl": "4.52.5",
+ "@rollup/rollup-linux-loong64-gnu": "4.52.5",
+ "@rollup/rollup-linux-ppc64-gnu": "4.52.5",
+ "@rollup/rollup-linux-riscv64-gnu": "4.52.5",
+ "@rollup/rollup-linux-riscv64-musl": "4.52.5",
+ "@rollup/rollup-linux-s390x-gnu": "4.52.5",
+ "@rollup/rollup-linux-x64-gnu": "4.52.5",
+ "@rollup/rollup-linux-x64-musl": "4.52.5",
+ "@rollup/rollup-openharmony-arm64": "4.52.5",
+ "@rollup/rollup-win32-arm64-msvc": "4.52.5",
+ "@rollup/rollup-win32-ia32-msvc": "4.52.5",
+ "@rollup/rollup-win32-x64-gnu": "4.52.5",
+ "@rollup/rollup-win32-x64-msvc": "4.52.5",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.21",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/packages/vite-plugin-lit-css/integration-test/package.json b/packages/vite-plugin-lit-css/integration-test/package.json
new file mode 100644
index 0000000..64bf553
--- /dev/null
+++ b/packages/vite-plugin-lit-css/integration-test/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "vite-plugin-lit-css-integration-test",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "build": "vite build",
+ "dev": "vite"
+ },
+ "dependencies": {
+ "lit": "^3.0.0"
+ },
+ "devDependencies": {
+ "vite": "^5.0.0"
+ }
+}
diff --git a/packages/vite-plugin-lit-css/integration-test/src/my-element.js b/packages/vite-plugin-lit-css/integration-test/src/my-element.js
new file mode 100644
index 0000000..5c41b05
--- /dev/null
+++ b/packages/vite-plugin-lit-css/integration-test/src/my-element.js
@@ -0,0 +1,15 @@
+import { LitElement, html } from 'lit';
+import styles from './styles.css';
+
+export class MyElement extends LitElement {
+ static styles = styles;
+
+ render() {
+ return html`
+ Hello from Vite + lit-css!
+ If this is styled with hotpink, the plugin works!
+ `;
+ }
+}
+
+customElements.define('my-element', MyElement);
diff --git a/packages/vite-plugin-lit-css/integration-test/src/styles.css b/packages/vite-plugin-lit-css/integration-test/src/styles.css
new file mode 100644
index 0000000..870a505
--- /dev/null
+++ b/packages/vite-plugin-lit-css/integration-test/src/styles.css
@@ -0,0 +1,9 @@
+:host {
+ display: block;
+ padding: 16px;
+}
+
+h1 {
+ color: hotpink;
+ font-size: 2rem;
+}
diff --git a/packages/vite-plugin-lit-css/integration-test/vite.config.js b/packages/vite-plugin-lit-css/integration-test/vite.config.js
new file mode 100644
index 0000000..b9d70bb
--- /dev/null
+++ b/packages/vite-plugin-lit-css/integration-test/vite.config.js
@@ -0,0 +1,18 @@
+import { defineConfig } from 'vite';
+import litCSS from '../vite-plugin-lit-css.js';
+
+export default defineConfig({
+ plugins: [
+ litCSS(),
+ ],
+ build: {
+ lib: {
+ entry: './src/my-element.js',
+ formats: ['es'],
+ fileName: 'my-element',
+ },
+ rollupOptions: {
+ external: ['lit'],
+ },
+ },
+});
diff --git a/packages/vite-plugin-lit-css/package.json b/packages/vite-plugin-lit-css/package.json
new file mode 100644
index 0000000..6ddbc69
--- /dev/null
+++ b/packages/vite-plugin-lit-css/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "vite-plugin-lit-css",
+ "description": "Vite plugin to import CSS files as tagged template literals",
+ "version": "1.0.0",
+ "type": "module",
+ "main": "vite-plugin-lit-css.js",
+ "types": "vite-plugin-lit-css.d.ts",
+ "exports": {
+ "import": "./vite-plugin-lit-css.js",
+ "require": "./vite-plugin-lit-css.cjs"
+ },
+ "author": "Benny Powers",
+ "license": "ISC",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/bennypowers/lit-css.git",
+ "directory": "packages/vite-plugin-lit-css"
+ },
+ "bugs": {
+ "url": "https://github.com/bennypowers/lit-css/issues"
+ },
+ "keywords": [
+ "lit",
+ "web-components",
+ "css",
+ "vite"
+ ],
+ "files": [
+ "vite-plugin-lit-css.cjs",
+ "vite-plugin-lit-css.js",
+ "vite-plugin-lit-css.d.ts"
+ ],
+ "dependencies": {
+ "@pwrs/lit-css": "^4.0.0",
+ "@rollup/pluginutils": "^5.1.4"
+ },
+ "peerDependencies": {
+ "vite": "^4.0.0 || ^5.0.0 || ^6.0.0"
+ }
+}
diff --git a/packages/vite-plugin-lit-css/test/expected/bare/output.js b/packages/vite-plugin-lit-css/test/expected/bare/output.js
new file mode 100644
index 0000000..4102af4
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/bare/output.js
@@ -0,0 +1,9 @@
+import { css } from "lit";
+const styles = css`html {
+ display: block;
+}
+`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/expected/basic/boop.js b/packages/vite-plugin-lit-css/test/expected/basic/boop.js
new file mode 100644
index 0000000..ff61ee8
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/basic/boop.js
@@ -0,0 +1,9 @@
+import { boop } from "snoot";
+const styles = boop`html {
+ display: block;
+}
+`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/expected/basic/fast.js b/packages/vite-plugin-lit-css/test/expected/basic/fast.js
new file mode 100644
index 0000000..373aa07
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/basic/fast.js
@@ -0,0 +1,9 @@
+import { css } from "@microsoft/fast-element";
+const styles = css`html {
+ display: block;
+}
+`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/expected/basic/output.js b/packages/vite-plugin-lit-css/test/expected/basic/output.js
new file mode 100644
index 0000000..4102af4
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/basic/output.js
@@ -0,0 +1,9 @@
+import { css } from "lit";
+const styles = css`html {
+ display: block;
+}
+`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/expected/basic/uglified.js b/packages/vite-plugin-lit-css/test/expected/basic/uglified.js
new file mode 100644
index 0000000..67173aa
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/basic/uglified.js
@@ -0,0 +1,6 @@
+import { css } from "lit";
+const styles = css`html{display:block}`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/expected/postcss/output.js b/packages/vite-plugin-lit-css/test/expected/postcss/output.js
new file mode 100644
index 0000000..2826985
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/postcss/output.js
@@ -0,0 +1,6 @@
+import { css } from "lit";
+const styles = css`html{display:block}html body{display:flex}`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/expected/scss/output.js b/packages/vite-plugin-lit-css/test/expected/scss/output.js
new file mode 100644
index 0000000..67173aa
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/scss/output.js
@@ -0,0 +1,6 @@
+import { css } from "lit";
+const styles = css`html{display:block}`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/expected/special-chars/output.js b/packages/vite-plugin-lit-css/test/expected/special-chars/output.js
new file mode 100644
index 0000000..d754d2b
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/expected/special-chars/output.js
@@ -0,0 +1,12 @@
+import { css } from "lit";
+const styles = css`@import '../specialChars';
+
+/** \`😀\` */
+html {
+ display: block;
+}
+`;
+export {
+ styles as default,
+ styles
+};
diff --git a/packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js b/packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js
new file mode 100644
index 0000000..4cadd66
--- /dev/null
+++ b/packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js
@@ -0,0 +1,66 @@
+import litCSS from '../vite-plugin-lit-css.js';
+
+import { dirname, join, resolve } from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { build } from 'vite';
+
+import { run } from '@lit-css/test/test.js';
+
+const dir = dirname(fileURLToPath(import.meta.url));
+
+const FIXTURES_DIR = join(dir, '..', '..', '..', 'test', '😁-FIXTURES');
+
+// type check
+litCSS({
+ include: ['*'],
+ exclude: ['*'],
+});
+
+run({
+ dir,
+ name: 'vite-plugin-lit-css',
+ async getCode(path, { options, alias } = {}) {
+ const input = resolve(FIXTURES_DIR, path);
+ const inputDir = dirname(input);
+
+ const result = await build({
+ configFile: false,
+ logLevel: 'warn',
+ build: {
+ lib: {
+ entry: input,
+ formats: ['es'],
+ fileName: 'output',
+ },
+ write: false,
+ minify: false,
+ rollupOptions: {
+ external: ['lit', '@microsoft/fast-element', 'snoot'],
+ },
+ },
+ resolve: {
+ alias: alias ? Object.fromEntries(
+ Object.entries(alias).map(([k, v]) => [k, resolve(inputDir, v)])
+ ) : {},
+ },
+ plugins: [
+ litCSS(options),
+ ],
+ });
+
+ // Vite build returns an array when using lib mode
+ const buildOutput = Array.isArray(result) ? result[0] : result;
+
+ if (!buildOutput || !buildOutput.output)
+ throw new Error('No output in build result');
+
+
+ const chunk = buildOutput.output.find(item => item.type === 'chunk');
+
+ if (!chunk)
+ throw new Error('No chunk found in build output');
+
+
+ return chunk.code;
+ },
+});
diff --git a/packages/vite-plugin-lit-css/vite-plugin-lit-css.ts b/packages/vite-plugin-lit-css/vite-plugin-lit-css.ts
new file mode 100644
index 0000000..c945e02
--- /dev/null
+++ b/packages/vite-plugin-lit-css/vite-plugin-lit-css.ts
@@ -0,0 +1,93 @@
+import type { Plugin } from 'vite';
+import type { Options } from '@pwrs/lit-css/lit-css';
+
+import { createFilter, type FilterPattern } from '@rollup/pluginutils';
+import { transform } from '@pwrs/lit-css';
+import { readFile } from 'node:fs/promises';
+
+export interface LitCSSOptions extends Omit {
+ /**
+ * Files to include for transformation
+ * @default /\.css$/i
+ */
+ include?: FilterPattern;
+ /**
+ * Files to exclude from transformation
+ */
+ exclude?: FilterPattern;
+}
+
+/**
+ * Vite plugin to import CSS files as tagged template literals
+ *
+ * @param options - Plugin configuration options
+ * @returns Vite plugin
+ */
+export function litCSS(options?: LitCSSOptions): Plugin {
+ const {
+ exclude,
+ include = /\.css$/i,
+ specifier,
+ tag,
+ ...rest
+ } = options ?? {};
+
+ const filter = createFilter(include, exclude);
+
+ return {
+ name: 'vite-plugin-lit-css',
+ enforce: 'pre', // Run before Vite's built-in CSS plugin
+
+ async resolveId(source, importer, options) {
+ // Don't process external imports
+ if (!importer) return null;
+
+ // Quick check: only process potential CSS-like files
+ // This is just a performance optimization - the filter does the real check
+ if (!source.endsWith('.css') && !source.endsWith('.scss') && !source.endsWith('.sass') &&
+ !source.endsWith('.less') && !source.endsWith('.styl'))
+ return null;
+
+
+ // Let other plugins (alias, etc.) resolve the import first
+ // This handles bare specifiers, relative paths, and absolute paths
+ const resolution = await this.resolve(source, importer, {
+ skipSelf: true, // Don't call ourselves recursively
+ ...options,
+ });
+
+ // If resolution failed or is marked external, let other plugins handle it
+ if (!resolution || resolution.external) return null;
+
+ // Now check if the RESOLVED path matches our filter
+ if (filter(resolution.id)) {
+ // Return with .js extension so Rollup treats it as JavaScript
+ // We use \0 prefix to mark this as a virtual module
+ return `\0${resolution.id}.lit-css.js`;
+ }
+
+ return null;
+ },
+
+ async load(id) {
+ // Check if this is one of our virtual modules
+ if (!id.includes('.lit-css.js')) return null;
+
+ // Extract the original CSS file path (remove \0 prefix and .lit-css.js suffix)
+ const cleanId = id.replace(/^\0/, '').replace(/\.lit-css\.js$/, '');
+
+ try {
+ const css = await readFile(cleanId, 'utf8');
+ const code = await transform({ css, specifier, tag, filePath: cleanId, ...rest });
+ return {
+ code,
+ map: { mappings: '' },
+ };
+ } catch (error) {
+ this.error(error?.message ?? String(error));
+ }
+ },
+ };
+}
+
+export default litCSS;