wc-mixin/vite.config.ts
Buddy 76d78e1925 Accept a CSSStyleSheet as css; move example CSS and templates into files
css is now string | CSSStyleSheet. A sheet is adopted as-is: into its own
shadow root, an enclosing shadow root, or document.adoptedStyleSheets for
light DOM at the document level. Strings behave as before.

The examples import their styles with `with { type: 'css' }` and their
static templates with `with { type: 'text' }`. Safari doesn't support those
yet, so vite.config.ts rewrites them into modules Vite builds: a constructed
CSSStyleSheet, or the file's text. npm run examples now just runs vite,
with root set in the config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 11:44:27 -08:00

43 lines
1.6 KiB
TypeScript

import { readFile } from 'node:fs/promises';
import { defineConfig, type Plugin } from 'vite';
const ATTRIBUTE_IMPORT =
/(from\s*)(['"])([^'"]+)\2\s*with\s*\{\s*type\s*:\s*(['"])(css|text)\4\s*\}/g;
/**
* Standard import attributes, built for browsers that don't support them yet (Safari):
*
* - `import sheet from './x.css' with { type: 'css' }` → a `CSSStyleSheet`
* - `import text from './x.html' with { type: 'text' }` → the file's contents as a string
*
* The attribute is rewritten to a query before Vite sees the import. `?raw` makes Vite's own CSS
* handling leave the file alone; `&sheet` is loaded here as a module that builds the stylesheet.
*/
function importAttributes(): Plugin {
return {
name: 'import-attributes',
enforce: 'pre',
transform(code, id) {
if (!/\.[cm]?[jt]s$/.test(id) || !code.includes('with')) return null;
const out = code.replace(
ATTRIBUTE_IMPORT,
(_, from: string, quote: string, path: string, _q: string, type: string) =>
`${from}${quote}${path}?raw${type === 'css' ? '&sheet' : ''}${quote}`,
);
return out === code ? null : { code: out, map: null };
},
async load(id) {
if (!id.endsWith('?raw&sheet')) return null;
const file = id.slice(0, -'?raw&sheet'.length);
this.addWatchFile(file);
const css = await readFile(file, 'utf8');
return `const sheet = new CSSStyleSheet();\nsheet.replaceSync(${JSON.stringify(css)});\nexport default sheet;\n`;
},
};
}
export default defineConfig({
root: 'examples',
plugins: [importAttributes()],
});