@cascivo/vite-plugin 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -1
- package/dist/index.d.mts +27 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +29 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/readme.body.md +23 -1
package/README.md
CHANGED
|
@@ -57,6 +57,27 @@ cascivo layers:
|
|
|
57
57
|
cascivo.theme, cascivo.blocks, cascivo.override;
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
## SSR: `cascivoSsr()`
|
|
61
|
+
|
|
62
|
+
The published `@cascivo/react` bundle ships per-component CSS as static
|
|
63
|
+
side-effect imports. Bundlers resolve these; a bare server-side ESM loader (Node
|
|
64
|
+
native, workerd) does not and throws `Unknown file extension ".css"` during SSR.
|
|
65
|
+
`cascivoSsr()` marks every `@cascivo/*` package `ssr.noExternal`, so Vite
|
|
66
|
+
processes their CSS imports instead of the runtime loading them raw:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// vite.config.ts — for TanStack Start, vite-ssr, Remix on Vite, workerd, …
|
|
70
|
+
import { cascivoSsr } from '@cascivo/vite-plugin'
|
|
71
|
+
|
|
72
|
+
export default defineConfig({
|
|
73
|
+
plugins: [cascivoSsr()],
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
You still import `@cascivo/react/styles.css` + a theme once in your root entry.
|
|
78
|
+
`cascivoSsr()` composes with `cascivoLayers()` in the same `plugins` array. Full
|
|
79
|
+
recipe: [docs/USING-WITH-VITE-SSR.md](https://github.com/cascivo/cascivo/blob/main/docs/USING-WITH-VITE-SSR.md).
|
|
80
|
+
|
|
60
81
|
## Scope
|
|
61
82
|
|
|
62
83
|
- **Vite only.** A webpack/Next.js loader is not included.
|
|
@@ -66,7 +87,8 @@ cascivo layers:
|
|
|
66
87
|
|
|
67
88
|
## API
|
|
68
89
|
|
|
69
|
-
- `cascivoLayers({ imports })` — the
|
|
90
|
+
- `cascivoLayers({ imports })` — the vendor CSS-layering plugin.
|
|
91
|
+
- `cascivoSsr()` — sets `ssr.noExternal` for every `@cascivo/*` package (SSR/workerd).
|
|
70
92
|
- `wrapCssInLayer(source, layer?)` — the underlying pure transform, exported for testing.
|
|
71
93
|
|
|
72
94
|
## Install
|
package/dist/index.d.mts
CHANGED
|
@@ -22,6 +22,11 @@ interface VitePlugin {
|
|
|
22
22
|
code: string;
|
|
23
23
|
map: null;
|
|
24
24
|
} | null | undefined;
|
|
25
|
+
config?: () => {
|
|
26
|
+
ssr: {
|
|
27
|
+
noExternal: RegExp[];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
25
30
|
}
|
|
26
31
|
interface CascivoLayersOptions {
|
|
27
32
|
/**
|
|
@@ -46,6 +51,27 @@ declare function wrapCssInLayer(source: string, layer?: string): string;
|
|
|
46
51
|
* own CSS pipeline processes it.
|
|
47
52
|
*/
|
|
48
53
|
declare function cascivoLayers(options: CascivoLayersOptions): VitePlugin;
|
|
54
|
+
/**
|
|
55
|
+
* Matches every `@cascivo/*` package specifier (`@cascivo/react`,
|
|
56
|
+
* `@cascivo/react/styles.css`, `@cascivo/charts`, …).
|
|
57
|
+
*/
|
|
58
|
+
declare const CASCIVO_PACKAGE_RE: RegExp;
|
|
59
|
+
/**
|
|
60
|
+
* Vite plugin that marks all `@cascivo/*` packages `ssr.noExternal`.
|
|
61
|
+
*
|
|
62
|
+
* The published `@cascivo/react` bundle ships per-component CSS as static
|
|
63
|
+
* side-effect imports (`import './button.css'`). A bundler resolves those at
|
|
64
|
+
* build time, but a bare server-side ESM loader (Node native, workerd) does not
|
|
65
|
+
* and throws `Unknown file extension ".css"`. Setting `ssr.noExternal` tells
|
|
66
|
+
* Vite to process these packages — CSS imports included — during SSR instead of
|
|
67
|
+
* leaving them for the runtime to load raw.
|
|
68
|
+
*
|
|
69
|
+
* The returned partial config is deep-merged by Vite (which concatenates
|
|
70
|
+
* `ssr.noExternal` arrays), so this composes with any existing `noExternal` the
|
|
71
|
+
* user set. Use for TanStack Start, vite-ssr, Remix on Vite, Astro SSR, and
|
|
72
|
+
* workerd/Cloudflare targets. See docs/USING-WITH-VITE-SSR.md.
|
|
73
|
+
*/
|
|
74
|
+
declare function cascivoSsr(): VitePlugin;
|
|
49
75
|
//#endregion
|
|
50
|
-
export { CascivoLayersOptions, VitePlugin, cascivoLayers, cascivoLayers as default, wrapCssInLayer };
|
|
76
|
+
export { CASCIVO_PACKAGE_RE, CascivoLayersOptions, VitePlugin, cascivoLayers, cascivoLayers as default, cascivoSsr, wrapCssInLayer };
|
|
51
77
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;AAiBA
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;AAiBA;;;;;;;;;;;;;;;UAAiB,UAAA;EACf,IAAA;EACA,OAAA;EACA,SAAA,IAAa,IAAA,UAAc,EAAA;IAAiB,IAAA;IAAc,GAAA;EAAA;EAC1D,MAAA;IAAiB,GAAA;MAAO,UAAA,EAAY,MAAM;IAAA;EAAA;AAAA;AAAA,UAG3B,oBAAA;;;;;;;AAuDuD;EA/CtE,OAAA,EAAS,MAAM;AAAA;;;AAkE8B;AAiB/C;;;iBA/DgB,cAAA,CAAe,MAAA,UAAgB,KAAgB;AA+DvB;;;;;AAAA,iBApCxB,aAAA,CAAc,OAAA,EAAS,oBAAA,GAAuB,UAAU;;;;;cAmB3D,kBAAA,EAAkB,MAAgB;;;;;;;;;;;;;;;;iBAiB/B,UAAA,IAAc,UAAU"}
|
package/dist/index.mjs
CHANGED
|
@@ -56,7 +56,35 @@ function cascivoLayers(options) {
|
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Matches every `@cascivo/*` package specifier (`@cascivo/react`,
|
|
61
|
+
* `@cascivo/react/styles.css`, `@cascivo/charts`, …).
|
|
62
|
+
*/
|
|
63
|
+
const CASCIVO_PACKAGE_RE = /^@cascivo\//;
|
|
64
|
+
/**
|
|
65
|
+
* Vite plugin that marks all `@cascivo/*` packages `ssr.noExternal`.
|
|
66
|
+
*
|
|
67
|
+
* The published `@cascivo/react` bundle ships per-component CSS as static
|
|
68
|
+
* side-effect imports (`import './button.css'`). A bundler resolves those at
|
|
69
|
+
* build time, but a bare server-side ESM loader (Node native, workerd) does not
|
|
70
|
+
* and throws `Unknown file extension ".css"`. Setting `ssr.noExternal` tells
|
|
71
|
+
* Vite to process these packages — CSS imports included — during SSR instead of
|
|
72
|
+
* leaving them for the runtime to load raw.
|
|
73
|
+
*
|
|
74
|
+
* The returned partial config is deep-merged by Vite (which concatenates
|
|
75
|
+
* `ssr.noExternal` arrays), so this composes with any existing `noExternal` the
|
|
76
|
+
* user set. Use for TanStack Start, vite-ssr, Remix on Vite, Astro SSR, and
|
|
77
|
+
* workerd/Cloudflare targets. See docs/USING-WITH-VITE-SSR.md.
|
|
78
|
+
*/
|
|
79
|
+
function cascivoSsr() {
|
|
80
|
+
return {
|
|
81
|
+
name: "cascivo:ssr-no-external",
|
|
82
|
+
config() {
|
|
83
|
+
return { ssr: { noExternal: [CASCIVO_PACKAGE_RE] } };
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
59
87
|
//#endregion
|
|
60
|
-
export { cascivoLayers, cascivoLayers as default, wrapCssInLayer };
|
|
88
|
+
export { CASCIVO_PACKAGE_RE, cascivoLayers, cascivoLayers as default, cascivoSsr, wrapCssInLayer };
|
|
61
89
|
|
|
62
90
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @cascivo/vite-plugin — layer JS-imported vendor CSS.\n *\n * The native recipe (`@import url('lib.css') layer(vendor)` from a CSS file) is\n * the primary, tooling-free way to tame third-party stylesheets — see\n * docs/THIRD-PARTY-CSS.md. What native CSS cannot do is layer a stylesheet\n * imported from JavaScript (`import 'lib/styles.css'`), which is how most JS\n * libraries ship. This plugin closes exactly that gap: it wraps configured\n * node_modules `.css` imports into a low-priority `@layer` at build time so the\n * cascivo layers always win.\n */\n\n/**\n * The subset of Vite's `Plugin` interface this package implements. Declared\n * structurally so the package doesn't require `vite`'s types to be resolvable;\n * the returned object is assignable to Vite's `Plugin`.\n */\nexport interface VitePlugin {\n name: string\n enforce?: 'pre' | 'post'\n transform?: (code: string, id: string) => { code: string; map: null } | null | undefined\n}\n\nexport interface CascivoLayersOptions {\n /**\n * Map a stylesheet's module id (matched against the tail of the resolved id,\n * e.g. `\"recharts/styles.css\"`) to the cascade layer it should live in\n * (typically `\"vendor\"`). The layer must be declared before the cascivo\n * layers in your app's order statement — the scaffold from `cascivo create`\n * already includes a `vendor` slot.\n */\n imports: Record<string, string>\n}\n\nconst IMPORT_RE = /@import\\s+[^;]+;/g\nconst CHARSET_RE = /^\\s*@charset\\s+[^;]+;/i\n\n/** Add `layer(<layer>)` to an `@import` statement that isn't already layered. */\nfunction layerizeImport(stmt: string, layer: string): string {\n if (/\\blayer\\b/.test(stmt)) return stmt\n const head = stmt.match(/@import\\s+(?:url\\([^)]*\\)|\"[^\"]*\"|'[^']*')/i)\n if (!head) return stmt\n return stmt.replace(head[0], `${head[0]} layer(${layer})`)\n}\n\n/**\n * Wrap a stylesheet's rules in `@layer <layer> { … }`. Because an `@import` may\n * not appear inside a layer block, top-level `@import`s are hoisted out and\n * rewritten to carry `layer(<layer>)` themselves; a leading `@charset` is kept\n * first. Pure string-in/string-out.\n */\nexport function wrapCssInLayer(source: string, layer = 'vendor'): string {\n let charset = ''\n let body = source\n const cm = body.match(CHARSET_RE)\n if (cm) {\n charset = `${cm[0].trim()}\\n`\n body = body.slice(cm[0].length)\n }\n const imports: string[] = []\n body = body.replace(IMPORT_RE, (stmt) => {\n imports.push(layerizeImport(stmt.trim(), layer))\n return ''\n })\n const importsBlock = imports.length > 0 ? `${imports.join('\\n')}\\n` : ''\n return `${charset}${importsBlock}@layer ${layer} {\\n${body.trim()}\\n}\\n`\n}\n\n/** Normalize a module id: drop the query/hash and Windows backslashes. */\nfunction normalizeId(id: string): string {\n return (id.split('?')[0] ?? id).replace(/\\\\/g, '/')\n}\n\n/**\n * Vite plugin that wraps configured node_modules stylesheets in a cascade\n * `@layer`. Runs `enforce: 'pre'` so it transforms the raw CSS before Vite's\n * own CSS pipeline processes it.\n */\nexport function cascivoLayers(options: CascivoLayersOptions): VitePlugin {\n const entries = Object.entries(options?.imports ?? {})\n return {\n name: 'cascivo:vendor-layers',\n enforce: 'pre',\n transform(code, id) {\n const clean = normalizeId(id)\n if (!clean.endsWith('.css') || !clean.includes('node_modules')) return null\n const match = entries.find(([key]) => clean.endsWith(key))\n if (!match) return null\n return { code: wrapCssInLayer(code, match[1]), map: null }\n },\n }\n}\n\nexport default cascivoLayers\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @cascivo/vite-plugin — layer JS-imported vendor CSS.\n *\n * The native recipe (`@import url('lib.css') layer(vendor)` from a CSS file) is\n * the primary, tooling-free way to tame third-party stylesheets — see\n * docs/THIRD-PARTY-CSS.md. What native CSS cannot do is layer a stylesheet\n * imported from JavaScript (`import 'lib/styles.css'`), which is how most JS\n * libraries ship. This plugin closes exactly that gap: it wraps configured\n * node_modules `.css` imports into a low-priority `@layer` at build time so the\n * cascivo layers always win.\n */\n\n/**\n * The subset of Vite's `Plugin` interface this package implements. Declared\n * structurally so the package doesn't require `vite`'s types to be resolvable;\n * the returned object is assignable to Vite's `Plugin`.\n */\nexport interface VitePlugin {\n name: string\n enforce?: 'pre' | 'post'\n transform?: (code: string, id: string) => { code: string; map: null } | null | undefined\n config?: () => { ssr: { noExternal: RegExp[] } }\n}\n\nexport interface CascivoLayersOptions {\n /**\n * Map a stylesheet's module id (matched against the tail of the resolved id,\n * e.g. `\"recharts/styles.css\"`) to the cascade layer it should live in\n * (typically `\"vendor\"`). The layer must be declared before the cascivo\n * layers in your app's order statement — the scaffold from `cascivo create`\n * already includes a `vendor` slot.\n */\n imports: Record<string, string>\n}\n\nconst IMPORT_RE = /@import\\s+[^;]+;/g\nconst CHARSET_RE = /^\\s*@charset\\s+[^;]+;/i\n\n/** Add `layer(<layer>)` to an `@import` statement that isn't already layered. */\nfunction layerizeImport(stmt: string, layer: string): string {\n if (/\\blayer\\b/.test(stmt)) return stmt\n const head = stmt.match(/@import\\s+(?:url\\([^)]*\\)|\"[^\"]*\"|'[^']*')/i)\n if (!head) return stmt\n return stmt.replace(head[0], `${head[0]} layer(${layer})`)\n}\n\n/**\n * Wrap a stylesheet's rules in `@layer <layer> { … }`. Because an `@import` may\n * not appear inside a layer block, top-level `@import`s are hoisted out and\n * rewritten to carry `layer(<layer>)` themselves; a leading `@charset` is kept\n * first. Pure string-in/string-out.\n */\nexport function wrapCssInLayer(source: string, layer = 'vendor'): string {\n let charset = ''\n let body = source\n const cm = body.match(CHARSET_RE)\n if (cm) {\n charset = `${cm[0].trim()}\\n`\n body = body.slice(cm[0].length)\n }\n const imports: string[] = []\n body = body.replace(IMPORT_RE, (stmt) => {\n imports.push(layerizeImport(stmt.trim(), layer))\n return ''\n })\n const importsBlock = imports.length > 0 ? `${imports.join('\\n')}\\n` : ''\n return `${charset}${importsBlock}@layer ${layer} {\\n${body.trim()}\\n}\\n`\n}\n\n/** Normalize a module id: drop the query/hash and Windows backslashes. */\nfunction normalizeId(id: string): string {\n return (id.split('?')[0] ?? id).replace(/\\\\/g, '/')\n}\n\n/**\n * Vite plugin that wraps configured node_modules stylesheets in a cascade\n * `@layer`. Runs `enforce: 'pre'` so it transforms the raw CSS before Vite's\n * own CSS pipeline processes it.\n */\nexport function cascivoLayers(options: CascivoLayersOptions): VitePlugin {\n const entries = Object.entries(options?.imports ?? {})\n return {\n name: 'cascivo:vendor-layers',\n enforce: 'pre',\n transform(code, id) {\n const clean = normalizeId(id)\n if (!clean.endsWith('.css') || !clean.includes('node_modules')) return null\n const match = entries.find(([key]) => clean.endsWith(key))\n if (!match) return null\n return { code: wrapCssInLayer(code, match[1]), map: null }\n },\n }\n}\n\n/**\n * Matches every `@cascivo/*` package specifier (`@cascivo/react`,\n * `@cascivo/react/styles.css`, `@cascivo/charts`, …).\n */\nexport const CASCIVO_PACKAGE_RE = /^@cascivo\\//\n\n/**\n * Vite plugin that marks all `@cascivo/*` packages `ssr.noExternal`.\n *\n * The published `@cascivo/react` bundle ships per-component CSS as static\n * side-effect imports (`import './button.css'`). A bundler resolves those at\n * build time, but a bare server-side ESM loader (Node native, workerd) does not\n * and throws `Unknown file extension \".css\"`. Setting `ssr.noExternal` tells\n * Vite to process these packages — CSS imports included — during SSR instead of\n * leaving them for the runtime to load raw.\n *\n * The returned partial config is deep-merged by Vite (which concatenates\n * `ssr.noExternal` arrays), so this composes with any existing `noExternal` the\n * user set. Use for TanStack Start, vite-ssr, Remix on Vite, Astro SSR, and\n * workerd/Cloudflare targets. See docs/USING-WITH-VITE-SSR.md.\n */\nexport function cascivoSsr(): VitePlugin {\n return {\n name: 'cascivo:ssr-no-external',\n config() {\n return { ssr: { noExternal: [CASCIVO_PACKAGE_RE] } }\n },\n }\n}\n\nexport default cascivoLayers\n"],"mappings":";AAmCA,MAAM,YAAY;AAClB,MAAM,aAAa;;AAGnB,SAAS,eAAe,MAAc,OAAuB;CAC3D,IAAI,YAAY,KAAK,IAAI,GAAG,OAAO;CACnC,MAAM,OAAO,KAAK,MAAM,6CAA6C;CACrE,IAAI,CAAC,MAAM,OAAO;CAClB,OAAO,KAAK,QAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,SAAS,MAAM,EAAE;AAC3D;;;;;;;AAQA,SAAgB,eAAe,QAAgB,QAAQ,UAAkB;CACvE,IAAI,UAAU;CACd,IAAI,OAAO;CACX,MAAM,KAAK,KAAK,MAAM,UAAU;CAChC,IAAI,IAAI;EACN,UAAU,GAAG,GAAG,EAAE,CAAC,KAAK,EAAE;EAC1B,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC,MAAM;CAChC;CACA,MAAM,UAAoB,CAAC;CAC3B,OAAO,KAAK,QAAQ,YAAY,SAAS;EACvC,QAAQ,KAAK,eAAe,KAAK,KAAK,GAAG,KAAK,CAAC;EAC/C,OAAO;CACT,CAAC;CACD,MAAM,eAAe,QAAQ,SAAS,IAAI,GAAG,QAAQ,KAAK,IAAI,EAAE,MAAM;CACtE,OAAO,GAAG,UAAU,aAAa,SAAS,MAAM,MAAM,KAAK,KAAK,EAAE;AACpE;;AAGA,SAAS,YAAY,IAAoB;CACvC,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC,MAAM,GAAA,CAAI,QAAQ,OAAO,GAAG;AACpD;;;;;;AAOA,SAAgB,cAAc,SAA2C;CACvE,MAAM,UAAU,OAAO,QAAQ,SAAS,WAAW,CAAC,CAAC;CACrD,OAAO;EACL,MAAM;EACN,SAAS;EACT,UAAU,MAAM,IAAI;GAClB,MAAM,QAAQ,YAAY,EAAE;GAC5B,IAAI,CAAC,MAAM,SAAS,MAAM,KAAK,CAAC,MAAM,SAAS,cAAc,GAAG,OAAO;GACvE,MAAM,QAAQ,QAAQ,MAAM,CAAC,SAAS,MAAM,SAAS,GAAG,CAAC;GACzD,IAAI,CAAC,OAAO,OAAO;GACnB,OAAO;IAAE,MAAM,eAAe,MAAM,MAAM,EAAE;IAAG,KAAK;GAAK;EAC3D;CACF;AACF;;;;;AAMA,MAAa,qBAAqB;;;;;;;;;;;;;;;;AAiBlC,SAAgB,aAAyB;CACvC,OAAO;EACL,MAAM;EACN,SAAS;GACP,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,kBAAkB,EAAE,EAAE;EACrD;CACF;AACF"}
|
package/package.json
CHANGED
package/readme.body.md
CHANGED
|
@@ -39,6 +39,27 @@ cascivo layers:
|
|
|
39
39
|
cascivo.theme, cascivo.blocks, cascivo.override;
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
## SSR: `cascivoSsr()`
|
|
43
|
+
|
|
44
|
+
The published `@cascivo/react` bundle ships per-component CSS as static
|
|
45
|
+
side-effect imports. Bundlers resolve these; a bare server-side ESM loader (Node
|
|
46
|
+
native, workerd) does not and throws `Unknown file extension ".css"` during SSR.
|
|
47
|
+
`cascivoSsr()` marks every `@cascivo/*` package `ssr.noExternal`, so Vite
|
|
48
|
+
processes their CSS imports instead of the runtime loading them raw:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// vite.config.ts — for TanStack Start, vite-ssr, Remix on Vite, workerd, …
|
|
52
|
+
import { cascivoSsr } from '@cascivo/vite-plugin'
|
|
53
|
+
|
|
54
|
+
export default defineConfig({
|
|
55
|
+
plugins: [cascivoSsr()],
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
You still import `@cascivo/react/styles.css` + a theme once in your root entry.
|
|
60
|
+
`cascivoSsr()` composes with `cascivoLayers()` in the same `plugins` array. Full
|
|
61
|
+
recipe: [docs/USING-WITH-VITE-SSR.md](https://github.com/cascivo/cascivo/blob/main/docs/USING-WITH-VITE-SSR.md).
|
|
62
|
+
|
|
42
63
|
## Scope
|
|
43
64
|
|
|
44
65
|
- **Vite only.** A webpack/Next.js loader is not included.
|
|
@@ -48,5 +69,6 @@ cascivo layers:
|
|
|
48
69
|
|
|
49
70
|
## API
|
|
50
71
|
|
|
51
|
-
- `cascivoLayers({ imports })` — the
|
|
72
|
+
- `cascivoLayers({ imports })` — the vendor CSS-layering plugin.
|
|
73
|
+
- `cascivoSsr()` — sets `ssr.noExternal` for every `@cascivo/*` package (SSR/workerd).
|
|
52
74
|
- `wrapCssInLayer(source, layer?)` — the underlying pure transform, exported for testing.
|