From 6f7f563fee4d3eb8af992c4601532922f8ffc22b Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Mon, 3 Nov 2025 08:16:52 +0200 Subject: [PATCH 1/5] feat(vite): add vite support --- README.md | 1 + package-lock.json | 250 ++++- packages/vite-plugin-lit-css/CHANGELOG.md | 12 + packages/vite-plugin-lit-css/README.md | 171 +++ .../integration-test/README.md | 40 + .../integration-test/index.html | 16 + .../integration-test/package-lock.json | 995 ++++++++++++++++++ .../integration-test/package.json | 15 + .../integration-test/src/my-element.js | 15 + .../integration-test/src/styles.css | 9 + .../integration-test/vite.config.js | 18 + packages/vite-plugin-lit-css/package.json | 40 + .../test/expected/bare/output.js | 8 + .../test/expected/basic/boop.js | 8 + .../test/expected/basic/fast.js | 8 + .../test/expected/basic/output.js | 8 + .../test/expected/basic/uglified.js | 5 + .../test/expected/postcss/output.js | 5 + .../test/expected/scss/output.js | 5 + .../test/expected/special-chars/output.js | 11 + .../test/vite-plugin-lit-css.test.js | 67 ++ .../vite-plugin-lit-css.ts | 93 ++ 22 files changed, 1748 insertions(+), 52 deletions(-) create mode 100644 packages/vite-plugin-lit-css/CHANGELOG.md create mode 100644 packages/vite-plugin-lit-css/README.md create mode 100644 packages/vite-plugin-lit-css/integration-test/README.md create mode 100644 packages/vite-plugin-lit-css/integration-test/index.html create mode 100644 packages/vite-plugin-lit-css/integration-test/package-lock.json create mode 100644 packages/vite-plugin-lit-css/integration-test/package.json create mode 100644 packages/vite-plugin-lit-css/integration-test/src/my-element.js create mode 100644 packages/vite-plugin-lit-css/integration-test/src/styles.css create mode 100644 packages/vite-plugin-lit-css/integration-test/vite.config.js create mode 100644 packages/vite-plugin-lit-css/package.json create mode 100644 packages/vite-plugin-lit-css/test/expected/bare/output.js create mode 100644 packages/vite-plugin-lit-css/test/expected/basic/boop.js create mode 100644 packages/vite-plugin-lit-css/test/expected/basic/fast.js create mode 100644 packages/vite-plugin-lit-css/test/expected/basic/output.js create mode 100644 packages/vite-plugin-lit-css/test/expected/basic/uglified.js create mode 100644 packages/vite-plugin-lit-css/test/expected/postcss/output.js create mode 100644 packages/vite-plugin-lit-css/test/expected/scss/output.js create mode 100644 packages/vite-plugin-lit-css/test/expected/special-chars/output.js create mode 100644 packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js create mode 100644 packages/vite-plugin-lit-css/vite-plugin-lit-css.ts diff --git a/README.md b/README.md index 63f6687..e0930a6 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,5 @@ In the mean time, enjoy importing your CSS into your component files. - [esbuild](./packages/esbuild-plugin-lit-css) - [Webpack](./packages/lit-css-loader) - [Rollup](./packages/rollup-plugin-lit-css) +- [Vite](./packages/vite-plugin-lit-css) - [TypeScript](./packages/typescript-transform-lit-css) diff --git a/package-lock.json b/package-lock.json index 8997fc8..65024c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2583,7 +2583,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2597,7 +2597,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, "engines": { "node": ">=6.0.0" } @@ -2606,7 +2606,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6.0.0" } @@ -2615,7 +2615,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -2626,13 +2626,13 @@ "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, + "devOptional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -3267,7 +3267,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3281,7 +3280,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3295,7 +3293,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3309,7 +3306,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3323,7 +3319,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3337,7 +3332,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3351,7 +3345,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3365,7 +3358,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3379,7 +3371,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3393,7 +3384,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3407,7 +3397,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3421,7 +3410,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3435,7 +3423,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3449,7 +3436,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3463,7 +3449,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3477,7 +3462,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3491,7 +3475,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3505,7 +3488,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3519,7 +3501,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3533,7 +3514,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4464,7 +4444,7 @@ "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4920,7 +4900,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": { @@ -7313,7 +7293,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, "optional": true, "os": [ @@ -7939,7 +7918,7 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/import-fresh": { @@ -8780,7 +8759,6 @@ "version": "1.21.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "dev": true, "optional": true, "bin": { "jiti": "bin/jiti.js" @@ -11367,7 +11345,6 @@ "version": "4.40.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", - "devOptional": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.7" @@ -11523,7 +11500,7 @@ "version": "1.88.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.88.0.tgz", "integrity": "sha512-sF6TWQqjFvr4JILXzG4ucGOLELkESHL+I5QJhh7CNaE+Yge0SI+ehCatsXhJ7ymU1hAFcIS3/PBpjdIbXoyVbg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.0", @@ -11544,7 +11521,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" @@ -11560,7 +11537,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" @@ -11789,7 +11766,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", @@ -12408,7 +12385,7 @@ "version": "5.39.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", - "dev": true, + "devOptional": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -12542,6 +12519,54 @@ "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/tinyglobby/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/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -13098,6 +13123,116 @@ "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/vite/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/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vscode-json-languageservice": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz", @@ -13617,10 +13752,10 @@ } }, "packages/esbuild-plugin-lit-css": { - "version": "3.0.2", + "version": "4.0.0", "license": "ISC", "dependencies": { - "@pwrs/lit-css": "^3.0.1" + "@pwrs/lit-css": "^4.0.0" }, "peerDependencies": { "esbuild": ">=0.16.17 || ^0.25.0", @@ -13628,7 +13763,7 @@ } }, "packages/esbuild-plugin-minify-html-literals": { - "version": "2.0.1", + "version": "3.0.0", "license": "ISC", "dependencies": { "minify-html-literals": "^1.3.5" @@ -13639,33 +13774,33 @@ }, "packages/lit-css": { "name": "@pwrs/lit-css", - "version": "3.0.1", + "version": "4.0.0", "license": "ISC", "dependencies": { "cssnano": "^7.0.7" } }, "packages/lit-css-loader": { - "version": "3.0.1", + "version": "4.0.0", "license": "ISC", "dependencies": { - "@pwrs/lit-css": "^3.0.1", + "@pwrs/lit-css": "^4.0.0", "loader-utils": "^3.3.1" } }, "packages/rollup-plugin-lit-css": { - "version": "5.0.2", + "version": "6.0.0", "license": "ISC", "dependencies": { - "@pwrs/lit-css": "^3.0.1", + "@pwrs/lit-css": "^4.0.0", "@rollup/pluginutils": "^5.1.4" } }, "packages/typescript-transform-lit-css": { - "version": "2.0.2", + "version": "3.0.0", "license": "ISC", "dependencies": { - "@pwrs/lit-css": "^3.0.1" + "@pwrs/lit-css": "^4.0.0" }, "peerDependencies": { "clean-css": "^5", @@ -13676,11 +13811,22 @@ "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": "3.0.2", + "version": "4.0.0", "license": "ISC", "dependencies": { - "@pwrs/lit-css": "^3.0.1", + "@pwrs/lit-css": "^4.0.0", "@rollup/pluginutils": "^5.1.4" } }, @@ -13689,9 +13835,9 @@ "version": "1.0.10", "license": "MIT", "dependencies": { - "esbuild-plugin-lit-css": "3.0.2", - "lit-css-loader": "3.0.1", - "rollup-plugin-lit-css": "5.0.2" + "esbuild-plugin-lit-css": "4.0.0", + "lit-css-loader": "4.0.0", + "rollup-plugin-lit-css": "6.0.0" } } } 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..05b8051 --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/bare/output.js @@ -0,0 +1,8 @@ +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..68b419a --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/basic/boop.js @@ -0,0 +1,8 @@ +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..6a8f65d --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/basic/fast.js @@ -0,0 +1,8 @@ +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..05b8051 --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/basic/output.js @@ -0,0 +1,8 @@ +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..22c18a9 --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/basic/uglified.js @@ -0,0 +1,5 @@ +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..d81673c --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/postcss/output.js @@ -0,0 +1,5 @@ +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..22c18a9 --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/scss/output.js @@ -0,0 +1,5 @@ +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..ff2d293 --- /dev/null +++ b/packages/vite-plugin-lit-css/test/expected/special-chars/output.js @@ -0,0 +1,11 @@ +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..9223bc4 --- /dev/null +++ b/packages/vite-plugin-lit-css/test/vite-plugin-lit-css.test.js @@ -0,0 +1,67 @@ +import litCSS from '../vite-plugin-lit-css.js'; +import aliasPlugin from '@rollup/plugin-alias'; + +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..68ac6e8 --- /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: any) { + this.error(error?.message ?? String(error)); + } + }, + }; +} + +export default litCSS; From d421008cdb1b5e2bfd6c6c08aecccb59089ab334 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Mon, 3 Nov 2025 08:23:35 +0200 Subject: [PATCH 2/5] style: lint --- .eslintignore | 1 + .../test/vite-plugin-lit-css.test.js | 9 ++++----- packages/vite-plugin-lit-css/vite-plugin-lit-css.ts | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.eslintignore b/.eslintignore index d550e7e..7ccecf3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,6 @@ packages/*/test/expected/**/*.js packages/*/test/TSPC_OUTPUT/**/*.js +packages/*/integration-test/**/*.js packages/*/*.js packages/*/*.cjs packages/*/*.js.map 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 index 9223bc4..4cadd66 100644 --- 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 @@ -1,5 +1,4 @@ import litCSS from '../vite-plugin-lit-css.js'; -import aliasPlugin from '@rollup/plugin-alias'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -52,15 +51,15 @@ run({ // Vite build returns an array when using lib mode const buildOutput = Array.isArray(result) ? result[0] : result; - if (!buildOutput || !buildOutput.output) { + if (!buildOutput || !buildOutput.output) throw new Error('No output in build result'); - } + const chunk = buildOutput.output.find(item => item.type === 'chunk'); - if (!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 index 68ac6e8..c945e02 100644 --- a/packages/vite-plugin-lit-css/vite-plugin-lit-css.ts +++ b/packages/vite-plugin-lit-css/vite-plugin-lit-css.ts @@ -45,14 +45,14 @@ export function litCSS(options?: LitCSSOptions): Plugin { // 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')) { + !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 + skipSelf: true, // Don't call ourselves recursively ...options, }); @@ -63,7 +63,7 @@ export function litCSS(options?: LitCSSOptions): Plugin { 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 `\0${resolution.id}.lit-css.js`; } return null; @@ -83,7 +83,7 @@ export function litCSS(options?: LitCSSOptions): Plugin { code, map: { mappings: '' }, }; - } catch (error: any) { + } catch (error) { this.error(error?.message ?? String(error)); } }, From 30cb55749c38ebdfcb315aa4b0c8d295067031e0 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Mon, 3 Nov 2025 08:23:38 +0200 Subject: [PATCH 3/5] docs: changeset --- .changeset/vite-plugin-lit-css.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .changeset/vite-plugin-lit-css.md 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 From 2340d36ff4d5247a59324e90a47c378fd640675d Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Mon, 3 Nov 2025 08:25:24 +0200 Subject: [PATCH 4/5] chore: update browserslist --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65024c7..30ccf6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4990,9 +4990,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001718", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", - "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "version": "1.0.30001753", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", + "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==", "funding": [ { "type": "opencollective", From cc8320c743c5306179558c0b946a0cfbf3080211 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Mon, 3 Nov 2025 08:30:46 +0200 Subject: [PATCH 5/5] test(vite): update goldens --- .../vite-plugin-lit-css/test/expected/bare/output.js | 9 +++++---- packages/vite-plugin-lit-css/test/expected/basic/boop.js | 9 +++++---- packages/vite-plugin-lit-css/test/expected/basic/fast.js | 9 +++++---- .../vite-plugin-lit-css/test/expected/basic/output.js | 9 +++++---- .../vite-plugin-lit-css/test/expected/basic/uglified.js | 9 +++++---- .../vite-plugin-lit-css/test/expected/postcss/output.js | 9 +++++---- .../vite-plugin-lit-css/test/expected/scss/output.js | 9 +++++---- .../test/expected/special-chars/output.js | 9 +++++---- 8 files changed, 40 insertions(+), 32 deletions(-) diff --git a/packages/vite-plugin-lit-css/test/expected/bare/output.js b/packages/vite-plugin-lit-css/test/expected/bare/output.js index 05b8051..4102af4 100644 --- a/packages/vite-plugin-lit-css/test/expected/bare/output.js +++ b/packages/vite-plugin-lit-css/test/expected/bare/output.js @@ -1,8 +1,9 @@ -import { css } from 'lit'; - +import { css } from "lit"; const styles = css`html { display: block; } `; - -export { styles as default, styles }; +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 index 68b419a..ff61ee8 100644 --- a/packages/vite-plugin-lit-css/test/expected/basic/boop.js +++ b/packages/vite-plugin-lit-css/test/expected/basic/boop.js @@ -1,8 +1,9 @@ -import { boop } from 'snoot'; - +import { boop } from "snoot"; const styles = boop`html { display: block; } `; - -export { styles as default, styles }; +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 index 6a8f65d..373aa07 100644 --- a/packages/vite-plugin-lit-css/test/expected/basic/fast.js +++ b/packages/vite-plugin-lit-css/test/expected/basic/fast.js @@ -1,8 +1,9 @@ -import { css } from '@microsoft/fast-element'; - +import { css } from "@microsoft/fast-element"; const styles = css`html { display: block; } `; - -export { styles as default, styles }; +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 index 05b8051..4102af4 100644 --- a/packages/vite-plugin-lit-css/test/expected/basic/output.js +++ b/packages/vite-plugin-lit-css/test/expected/basic/output.js @@ -1,8 +1,9 @@ -import { css } from 'lit'; - +import { css } from "lit"; const styles = css`html { display: block; } `; - -export { styles as default, styles }; +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 index 22c18a9..67173aa 100644 --- a/packages/vite-plugin-lit-css/test/expected/basic/uglified.js +++ b/packages/vite-plugin-lit-css/test/expected/basic/uglified.js @@ -1,5 +1,6 @@ -import { css } from 'lit'; - +import { css } from "lit"; const styles = css`html{display:block}`; - -export { styles as default, styles }; +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 index d81673c..2826985 100644 --- a/packages/vite-plugin-lit-css/test/expected/postcss/output.js +++ b/packages/vite-plugin-lit-css/test/expected/postcss/output.js @@ -1,5 +1,6 @@ -import { css } from 'lit'; - +import { css } from "lit"; const styles = css`html{display:block}html body{display:flex}`; - -export { styles as default, styles }; +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 index 22c18a9..67173aa 100644 --- a/packages/vite-plugin-lit-css/test/expected/scss/output.js +++ b/packages/vite-plugin-lit-css/test/expected/scss/output.js @@ -1,5 +1,6 @@ -import { css } from 'lit'; - +import { css } from "lit"; const styles = css`html{display:block}`; - -export { styles as default, styles }; +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 index ff2d293..d754d2b 100644 --- a/packages/vite-plugin-lit-css/test/expected/special-chars/output.js +++ b/packages/vite-plugin-lit-css/test/expected/special-chars/output.js @@ -1,5 +1,4 @@ -import { css } from 'lit'; - +import { css } from "lit"; const styles = css`@import '../specialChars'; /** \`😀\` */ @@ -7,5 +6,7 @@ html { display: block; } `; - -export { styles as default, styles }; +export { + styles as default, + styles +};