vite-plugin-css-position 3.0.0-next.1 → 3.0.0-next.2

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 CHANGED
@@ -40,7 +40,7 @@ Add the plugin to your `vite.config.ts`:
40
40
  import { viteCssPosition } from "vite-plugin-css-position";
41
41
 
42
42
  export default defineConfig({
43
- plugins: [react(), /* or vue(), */ viteCssPosition({ cssPerChunk: true })],
43
+ plugins: [react(), /* or vue(), */ viteCssPosition({ mode: "injectPerChunk" /* or cssChunks */ })],
44
44
  });
45
45
  ```
46
46
 
@@ -97,7 +97,6 @@ viteCssPosition({
97
97
  - **`mode`** - How CSS is delivered and registered. Defaults to `"inject"`. See [Modes](#modes) below.
98
98
  - **`cssChunksStrategy`** - Only used when `mode: "cssChunks"`. `"link"` (default) renders `<link rel="stylesheet">`; `"adopt"` fetches the CSS and applies it via `adoptedStyleSheets`. See [Modes](#modes).
99
99
  - **`jsAssetsFilterFunction`** - Filter function `(chunk) => boolean` to control which JS output chunk(s) receive the CSS injection code. Useful with multiple entry points.
100
- - **`cssPerChunk`** _(deprecated)_ - Use `mode` instead. `true` maps to `mode: "injectPerChunk"`, `false`/unset to `mode: "inject"`. Ignored when `mode` is set.
101
100
 
102
101
  ### Modes
103
102
 
package/dist/index.d.ts CHANGED
@@ -18,8 +18,7 @@ interface BaseCssPositionOptions {
18
18
  }
19
19
  /**
20
20
  * Mode-specific options. A discriminated union so that `cssChunksStrategy` is
21
- * only assignable when `mode: "cssChunks"`, and the deprecated `cssPerChunk` is
22
- * only assignable for the inline-inject modes.
21
+ * only assignable when `mode: "cssChunks"`.
23
22
  */
24
23
  type ModeCssPositionOptions = {
25
24
  /**
@@ -32,11 +31,6 @@ type ModeCssPositionOptions = {
32
31
  * @default "inject"
33
32
  */
34
33
  mode?: "inject" | "injectPerChunk";
35
- /**
36
- * @deprecated Use `mode` instead. `true` maps to `mode: "injectPerChunk"`,
37
- * `false`/unset to `mode: "inject"`. Ignored when `mode` is set.
38
- */
39
- cssPerChunk?: boolean;
40
34
  /** Only valid with `mode: "cssChunks"`. */
41
35
  cssChunksStrategy?: never;
42
36
  } | {
@@ -56,8 +50,6 @@ type ModeCssPositionOptions = {
56
50
  * @default "link"
57
51
  */
58
52
  cssChunksStrategy?: CssChunksStrategy;
59
- /** Not applicable in `cssChunks` mode. */
60
- cssPerChunk?: never;
61
53
  };
62
54
  type ViteCustomCssPositionOptions = BaseCssPositionOptions & ModeCssPositionOptions;
63
55
  declare function viteCustomCssPosition(options?: ViteCustomCssPositionOptions): Plugin | Plugin[];
package/dist/index.js CHANGED
@@ -5,5 +5,5 @@ import{hash as e,randomUUID as t}from"crypto";import{posix as n}from"node:path";
5
5
  }
6
6
  })()`}const c={};function l(e,t){let n=e[t];if(n!==void 0&&n.source){let e=n.source;c[t]=e instanceof Uint8Array?new TextDecoder().decode(e):`${e}`}return c[t]??``}function u(e,t){return t.reduce((t,n)=>{let r=l(e,n);return delete e[n],t+r},``)}function d(e){return e.type==`chunk`&&e.fileName.match(/.[cm]?js(?:\?.+)?$/)!=null}function f(e){return e.isEntry&&!e.fileName.includes(`polyfill`)}function p(e,t){if(typeof t!=`function`){let t=Object.keys(e).filter(t=>{let n=e[t];return n!==void 0&&d(n)&&f(n)}),n=t[t.length-1];return n===void 0?[]:(t.length>1&&i(`[vite-plugin-css-position] identified "${n}" as one of multiple "entry" output files to put the CSS injection code. If this is not the intended file, use the "jsAssetsFilterFunction" option to specify the desired output file.`),[n])}return Object.entries(e).filter(([,e])=>d(e)&&t(e)).map(([e])=>e)}function m(e,t){let n={},i=p(e,typeof t==`function`?t:()=>!0);if(i.length===0)throw Error(`Unable to locate the JavaScript asset for adding the CSS injection code. It is recommended to review your configurations.`);for(let t of i){let i=e[t];if(i===void 0||i.type===`asset`)continue;let a=r(i);if(!a||a.size===0)continue;let o=n[t]||[];o.push(...a.values()),n[t]=o}return n}function h(e,t,n){let r=e.replace(/\/\*\s*empty css\s*\*\//g,``);return e=n?``:r,e+=t,e+=n?r:``,e}function g(e,t){for(let n in e){let r=e[n];if(r===void 0||r.type!==`chunk`)continue;let i=r.viteMetadata;i&&i.importedCss.size>0&&i.importedCss.forEach(e=>{t.includes(e)||(i.importedCss=new Set)})}}function _(e,t){let n=RegExp(`<link rel=".*"[^>]*?href=".*/?${t}"[^>]*?>`);return e.replace(n,``)}function v(e){return/\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/.test(e)}function y(e,t,n){for(let[r,i]of Object.entries(t)){let t=u(e,i),a=t.length>0?n(t):``,o=e[r];o.code=h(o.code,a,!0)}}const b=new Map;let x=``;function S(e,t,n,r){let i=p(e,r);if(i.length==0)throw Error(`Unable to locate the JavaScript asset for adding the CSS injection code. It is recommended to review your configurations.`);let a=u(e,t),o=a.length>0?n(a):``;for(let t of i){let n=e[t];n.facadeModuleId!=null&&n.isEntry&&o!=``&&(n.facadeModuleId!=x&&b.clear(),x=n.facadeModuleId,b.set(n.facadeModuleId,o)),o==``&&n.isEntry&&n.facadeModuleId!=null&&typeof b.get(n.facadeModuleId)==`string`&&(o=b.get(n.facadeModuleId)),n.code=h(n.code,o,!0)}}function C(e){return e.startsWith(`.`)?e:`./`+e}function w(t,r,i,a){for(let[s,c]of Object.entries(r)){let r=t[s],l=n.dirname(r.fileName),u=o(i,a,c.map(t=>({id:e(`sha1`,t).substring(0,12),rel:C(n.relative(l,t))})));r.code=h(r.code,u,!0)}}function T(e){let t=e.match(/m\.f=\[([^\]]*)\]/);if(!t||t[1]===void 0)return e;let n=[...t[1].matchAll(/"((?:[^"\\]|\\.)*)"/g)].map(e=>e[1]),r=new Set;return n.forEach((e,t)=>{e!==void 0&&e.endsWith(`.css`)&&r.add(t)}),r.size===0?e:e.replace(/__vite__mapDeps\(\[([^\]]*)\]\)/g,(e,t)=>`__vite__mapDeps([${t.split(`,`).map(e=>e.trim()).filter(e=>e!==``&&!r.has(Number(e))).join(`,`)}])`)}function E(e){let{globalVarName:t,eventName:n,mode:r,jsAssetsFilterFunction:o}=e,c=r===`injectPerChunk`||r===`cssChunks`,l,u=[{apply:`build`,enforce:`post`,name:`vite-plugin-css-position-injection`,config(e,t){t.command===`build`&&c&&(e.build??={},e.build.cssCodeSplit===!1&&i(`[vite-plugin-css-position] Override of 'build.cssCodeSplit' to true; it must be true when mode is '${r}'.`),e.build.cssCodeSplit=!0)},configResolved(e){l=e},generateBundle(e,s){if(l.build.ssr)return;let c=Object.keys(s).filter(e=>{let t=s[e];return t!==void 0&&t.type==`asset`&&t.fileName.endsWith(`.css`)}),u=[];if(r===`cssChunks`)w(s,m(s,o),t,n);else{let e=e=>a(t,n,JSON.stringify(e.trim()));r===`injectPerChunk`?(y(s,m(s,o),e),u=c.filter(e=>!!s[e]),u.length>0&&i(`[vite-plugin-css-position] Some CSS assets were not included in any known JS: ${u.join(`,`)}`)):S(s,c,e,o),g(s,u)}let d=Object.keys(s).filter(e=>e.endsWith(`.html`));for(let e of d){let t=s[e],n=t.source instanceof Uint8Array?new TextDecoder().decode(t.source):`${t.source}`;c.forEach(e=>{u.includes(e)||(n=_(n,e),t.source=n)})}}}];return r===`cssChunks`&&u.push({apply:`build`,enforce:`post`,name:`vite-plugin-css-position-preload-strip`,generateBundle:{order:`post`,handler(e,t){for(let e of Object.keys(t)){let n=t[e];n!==void 0&&n.type===`chunk`&&(n.code=T(n.code))}}}}),e.enableDev&&(i(`[vite-plugin-css-position] Experimental dev mode activated!`),u.push({name:`vite-plugin-css-position-injection-dev`,apply:`serve`,enforce:`post`,transform(e,r){if(!v(r))return;let i=s(t,n,r),o=a(t,n,`__vite__css`,{type:`text/css`,"data-vite-dev-id":r}),c=e.replace(`__vite__updateStyle(__vite__id, __vite__css)`,`;
7
7
  `+i+`;
8
- `+o);return c=c.replace(`__vite__removeStyle(__vite__id)`,i),{code:c,map:null}}})),u}function D(e){return e?.mode?(e.cssPerChunk!==void 0&&console.warn(`[vite-plugin-css-position] Both 'mode' and the deprecated 'cssPerChunk' are set; 'mode' wins.`),e.mode):e?.cssPerChunk?`injectPerChunk`:`inject`}function O(e){let n=e?.instanceId||t().replace(/-/g,``).slice(0,4),r=`__vcssp_c_${n}`,i=`__vcssp_e_${n}`,a=e?.cssChunksStrategy??`link`;return[{name:`vite-plugin-custom-css-position`,config(e){return{...e,define:{...e.define,__VITE_CSS_POS_GLOBAL_VAR_NAME__:JSON.stringify(r),__VITE_CSS_POS_EVENT_NAME__:JSON.stringify(i),__VITE_CSS_POS_LINK_STRATEGY__:JSON.stringify(a)}}}},...E({globalVarName:r,eventName:i,enableDev:e?.enableDev??!1,mode:D(e),jsAssetsFilterFunction:e?.jsAssetsFilterFunction})]}export{O as viteCssPosition,O as viteReactCssPosition};
8
+ `+o);return c=c.replace(`__vite__removeStyle(__vite__id)`,i),{code:c,map:null}}})),u}function D(e){let n=e?.instanceId||t().replace(/-/g,``).slice(0,4),r=`__vcssp_c_${n}`,i=`__vcssp_e_${n}`,a=e?.cssChunksStrategy??`link`;return[{name:`vite-plugin-custom-css-position`,config(e){return{...e,define:{...e.define,__VITE_CSS_POS_GLOBAL_VAR_NAME__:JSON.stringify(r),__VITE_CSS_POS_EVENT_NAME__:JSON.stringify(i),__VITE_CSS_POS_LINK_STRATEGY__:JSON.stringify(a)}}}},...E({globalVarName:r,eventName:i,enableDev:e?.enableDev??!1,mode:e?.mode??`inject`,jsAssetsFilterFunction:e?.jsAssetsFilterFunction})]}export{D as viteCssPosition,D as viteReactCssPosition};
9
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["cssSourceCache: Record<string, string>","chunksWithCss: Record<string, string[]>","config: ResolvedConfig","plugins: Plugin[]","unusedCssAssets: string[]","linkStrategy: CssChunksStrategy"],"sources":["../src/cssInjection.ts","../src/viteCustomCssPosition.ts"],"sourcesContent":["/**\n * CSS-by-JS injection core, vendored and trimmed from\n * `vite-plugin-css-injected-by-js` (v3.5.2) by Marco Prontera.\n *\n * Original: https://github.com/marco-prontera/vite-plugin-css-injected-by-js\n * Licensed under the MIT License — Copyright (c) 2023 Marco Prontera.\n *\n * This is a focused port: instead of creating `<style>` elements directly, the\n * generated injection code stores the CSS into a global Map and dispatches an\n * event, which the `StylesTarget` component reacts to in order to render the\n * styles at a custom position (e.g. inside a Shadow DOM). Unlike the original it\n * does NOT run a nested Vite build to produce the injection code; the snippet is\n * built directly and wrapped in an IIFE.\n *\n * Beyond the original's CSS-in-JS modes (`inject`/`injectPerChunk`), this module\n * adds a `cssChunks` mode that keeps Vite's emitted `.css` chunk files and only\n * registers their URLs per chunk, so `StylesTarget` can link/adopt them at its\n * position instead of inlining the CSS.\n */\nimport { hash } from \"crypto\";\nimport { posix } from \"node:path\";\nimport type { Plugin, ResolvedConfig, Rollup } from \"vite\";\n\n/**\n * - `inject`: concatenate all CSS into the entry chunk JS, registered as `<style>`.\n * - `injectPerChunk`: inline each chunk's CSS into its JS, registered as `<style>`.\n * - `cssChunks`: keep emitted `.css` files; register their URLs per chunk so they\n * can be linked/adopted at the `StylesTarget` position.\n */\nexport type InjectionMode = \"inject\" | \"injectPerChunk\" | \"cssChunks\";\n\nexport interface CssInjectionOptions {\n /** Name of the global variable holding the styles Map. */\n globalVarName: string;\n /** Name of the window event dispatched on style updates. */\n eventName: string;\n /** Enable the experimental dev-mode (HMR) transform. */\n enableDev: boolean;\n /** How CSS is delivered and registered. See {@link InjectionMode}. */\n mode: InjectionMode;\n /** Filter which JS chunks receive the CSS injection code. */\n jsAssetsFilterFunction?: ((chunk: Rollup.OutputChunk) => boolean) | undefined;\n}\n\n// CSS is injected before the rest of the chunk's code (parity with the original\n// plugin's default `topExecutionPriority: true`).\nconst TOP_EXECUTION_PRIORITY = true;\n\n// `viteMetadata.importedCss` is a Vite augmentation of Rollup's chunk type that\n// isn't surfaced through Vite's re-exported `Rollup` namespace; access it via a\n// local typed view.\ntype ChunkWithCssMeta = Rollup.OutputChunk & {\n viteMetadata?: { importedCss: Set<string> };\n};\n\nfunction importedCssOf(chunk: Rollup.OutputChunk): Set<string> | undefined {\n return (chunk as ChunkWithCssMeta).viteMetadata?.importedCss;\n}\n\nfunction warnLog(msg: string): void {\n console.warn(`\\x1b[33m \\n${msg} \\x1b[39m`);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Injection code generation */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Build the runtime snippet that registers the given CSS in the global Map and\n * notifies listeners. Wrapped in an IIFE so the local `const`s don't leak into\n * (or collide within) the chunk scope it is appended to.\n *\n * @param cssCodeExpr A JS expression evaluating to the CSS string. In build mode\n * this is a JSON string literal; in dev mode it's the `__vite__css` variable.\n * @param attributes Attributes to attach to the rendered `<style>` (dev only).\n */\nfunction buildInjectionCode(\n globalVarName: string,\n eventName: string,\n cssCodeExpr: string,\n attributes?: Record<string, string>\n): string {\n const attributesString = JSON.stringify(attributes || {});\n const id = `\"${\n attributes?.[\"data-vite-dev-id\"] ?? hash(\"sha1\", cssCodeExpr).substring(0, 12)\n }\"`;\n const body =\n `const css = ${cssCodeExpr};const id = ${id};const attributes = JSON.parse('${attributesString}');` +\n `window.${globalVarName} = window.${globalVarName} || new Map();` +\n `window.${globalVarName}.set(id, {type:\"style\", css, attributes});` +\n `window.dispatchEvent( new Event('${eventName}') );`;\n return `(()=>{${body}})();`;\n}\n\n/**\n * Build the runtime snippet (cssChunks mode) that registers emitted CSS file\n * URLs in the global Map. URLs are resolved relative to the chunk via\n * `import.meta.url`, which is base-agnostic (works for relative and absolute base).\n */\nfunction buildLinkRegistrationCode(\n globalVarName: string,\n eventName: string,\n items: Array<{ id: string; rel: string }>\n): string {\n const data = JSON.stringify(items.map((it) => [it.id, it.rel]));\n return (\n `(()=>{const items=${data};` +\n `window.${globalVarName}=window.${globalVarName}||new Map();` +\n `for(const [id,rel] of items){` +\n `window.${globalVarName}.set(id,{type:\"link\",href:new URL(rel,import.meta.url).href,attributes:{}});}` +\n `window.dispatchEvent(new Event('${eventName}'));})();`\n );\n}\n\n/** Code executed (dev mode) to remove a previously injected style on HMR update. */\nfunction buildRemoveStyleCode(globalVarName: string, eventName: string, id: string): string {\n return `(() => {\n if(window.${globalVarName} && window.${globalVarName}.has('${id}')) {\n window.${globalVarName}.delete('${id}');\n window.dispatchEvent( new Event('${eventName}') );\n }\n })()`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Bundle helpers (ported from vite-plugin-css-injected-by-js utils) */\n/* -------------------------------------------------------------------------- */\n\n// The cache must be global since the execution context differs per entry.\nconst cssSourceCache: Record<string, string> = {};\n\nfunction extractCss(bundle: Rollup.OutputBundle, cssName: string): string {\n const cssAsset = bundle[cssName] as Rollup.OutputAsset | undefined;\n if (cssAsset !== undefined && cssAsset.source) {\n const cssSource = cssAsset.source;\n cssSourceCache[cssName] =\n cssSource instanceof Uint8Array ? new TextDecoder().decode(cssSource) : `${cssSource}`;\n }\n return cssSourceCache[cssName] ?? \"\";\n}\n\nfunction concatCssAndDeleteFromBundle(bundle: Rollup.OutputBundle, cssAssets: string[]): string {\n return cssAssets.reduce((previous, cssName) => {\n const cssSource = extractCss(bundle, cssName);\n delete bundle[cssName];\n return previous + cssSource;\n }, \"\");\n}\n\nfunction isJsOutputChunk(chunk: Rollup.OutputAsset | Rollup.OutputChunk): chunk is Rollup.OutputChunk {\n return chunk.type == \"chunk\" && chunk.fileName.match(/.[cm]?js(?:\\?.+)?$/) != null;\n}\n\nfunction defaultJsAssetsFilter(chunk: Rollup.OutputChunk): boolean {\n return chunk.isEntry && !chunk.fileName.includes(\"polyfill\");\n}\n\nfunction getJsTargetBundleKeys(\n bundle: Rollup.OutputBundle,\n jsAssetsFilterFunction?: (chunk: Rollup.OutputChunk) => boolean\n): string[] {\n if (typeof jsAssetsFilterFunction != \"function\") {\n const jsAssets = Object.keys(bundle).filter((i) => {\n const asset = bundle[i];\n return asset !== undefined && isJsOutputChunk(asset) && defaultJsAssetsFilter(asset);\n });\n const jsTargetFileName = jsAssets[jsAssets.length - 1];\n if (jsTargetFileName === undefined) {\n return [];\n }\n if (jsAssets.length > 1) {\n warnLog(\n `[vite-plugin-css-position] identified \"${jsTargetFileName}\" as one of multiple \"entry\" output files to put the CSS injection code. ` +\n 'If this is not the intended file, use the \"jsAssetsFilterFunction\" option to specify the desired output file.'\n );\n }\n return [jsTargetFileName];\n }\n return Object.entries(bundle)\n .filter(([, chunk]) => isJsOutputChunk(chunk) && jsAssetsFilterFunction(chunk))\n .map(([key]) => key);\n}\n\nfunction buildJsCssMap(\n bundle: Rollup.OutputBundle,\n jsAssetsFilterFunction?: (chunk: Rollup.OutputChunk) => boolean\n): Record<string, string[]> {\n const chunksWithCss: Record<string, string[]> = {};\n const bundleKeys = getJsTargetBundleKeys(\n bundle,\n typeof jsAssetsFilterFunction == \"function\" ? jsAssetsFilterFunction : () => true\n );\n if (bundleKeys.length === 0) {\n throw new Error(\n \"Unable to locate the JavaScript asset for adding the CSS injection code. It is recommended to review your configurations.\"\n );\n }\n for (const key of bundleKeys) {\n const chunk = bundle[key];\n if (chunk === undefined || chunk.type === \"asset\") {\n continue;\n }\n const importedCss = importedCssOf(chunk);\n if (!importedCss || importedCss.size === 0) {\n continue;\n }\n const chunkStyles = chunksWithCss[key] || [];\n chunkStyles.push(...importedCss.values());\n chunksWithCss[key] = chunkStyles;\n }\n return chunksWithCss;\n}\n\nfunction buildOutputChunkWithCssInjectionCode(\n jsAssetCode: string,\n cssInjectionCode: string,\n topExecutionPriorityFlag: boolean\n): string {\n const appCode = jsAssetCode.replace(/\\/\\*\\s*empty css\\s*\\*\\//g, \"\");\n jsAssetCode = topExecutionPriorityFlag ? \"\" : appCode;\n jsAssetCode += cssInjectionCode;\n jsAssetCode += !topExecutionPriorityFlag ? \"\" : appCode;\n return jsAssetCode;\n}\n\nfunction clearImportedCssViteMetadataFromBundle(\n bundle: Rollup.OutputBundle,\n unusedCssAssets: string[]\n): void {\n // Required to exclude removed files from manifest.json\n for (const key in bundle) {\n const chunk = bundle[key];\n if (chunk === undefined || chunk.type !== \"chunk\") {\n continue;\n }\n const meta = (chunk as ChunkWithCssMeta).viteMetadata;\n if (meta && meta.importedCss.size > 0) {\n meta.importedCss.forEach((importedCssFileName: string) => {\n if (!unusedCssAssets.includes(importedCssFileName)) {\n meta.importedCss = new Set();\n }\n });\n }\n }\n}\n\nfunction removeLinkStyleSheets(html: string, cssFileName: string): string {\n const removeCSS = new RegExp(`<link rel=\".*\"[^>]*?href=\".*/?${cssFileName}\"[^>]*?>`);\n return html.replace(removeCSS, \"\");\n}\n\nfunction isCSSRequest(request: string): boolean {\n const CSS_LANGS_RE = /\\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\\?)/;\n return CSS_LANGS_RE.test(request);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Injection modes */\n/* -------------------------------------------------------------------------- */\n\nfunction relativeCssInjection(\n bundle: Rollup.OutputBundle,\n assetsWithCss: Record<string, string[]>,\n makeInjection: (css: string) => string\n): void {\n for (const [jsAssetName, cssAssets] of Object.entries(assetsWithCss)) {\n const assetCss = concatCssAndDeleteFromBundle(bundle, cssAssets);\n const cssInjectionCode = assetCss.length > 0 ? makeInjection(assetCss) : \"\";\n const jsAsset = bundle[jsAssetName] as Rollup.OutputChunk;\n jsAsset.code = buildOutputChunkWithCssInjectionCode(\n jsAsset.code,\n cssInjectionCode,\n TOP_EXECUTION_PRIORITY\n );\n }\n}\n\n// Reuse CSS across sequential builds for the same entry (e.g. multiple formats).\nconst globalCSSCodeEntryCache = new Map<string, string>();\nlet previousFacadeModuleId = \"\";\n\nfunction globalCssInjection(\n bundle: Rollup.OutputBundle,\n cssAssets: string[],\n makeInjection: (css: string) => string,\n jsAssetsFilterFunction: ((chunk: Rollup.OutputChunk) => boolean) | undefined\n): void {\n const jsTargetBundleKeys = getJsTargetBundleKeys(bundle, jsAssetsFilterFunction);\n if (jsTargetBundleKeys.length == 0) {\n throw new Error(\n \"Unable to locate the JavaScript asset for adding the CSS injection code. It is recommended to review your configurations.\"\n );\n }\n const allCssCode = concatCssAndDeleteFromBundle(bundle, cssAssets);\n let cssInjectionCode = allCssCode.length > 0 ? makeInjection(allCssCode) : \"\";\n\n for (const jsTargetKey of jsTargetBundleKeys) {\n const jsAsset = bundle[jsTargetKey] as Rollup.OutputChunk;\n if (jsAsset.facadeModuleId != null && jsAsset.isEntry && cssInjectionCode != \"\") {\n if (jsAsset.facadeModuleId != previousFacadeModuleId) {\n globalCSSCodeEntryCache.clear();\n }\n previousFacadeModuleId = jsAsset.facadeModuleId;\n globalCSSCodeEntryCache.set(jsAsset.facadeModuleId, cssInjectionCode);\n }\n if (\n cssInjectionCode == \"\" &&\n jsAsset.isEntry &&\n jsAsset.facadeModuleId != null &&\n typeof globalCSSCodeEntryCache.get(jsAsset.facadeModuleId) == \"string\"\n ) {\n cssInjectionCode = globalCSSCodeEntryCache.get(jsAsset.facadeModuleId) as string;\n }\n jsAsset.code = buildOutputChunkWithCssInjectionCode(\n jsAsset.code,\n cssInjectionCode,\n TOP_EXECUTION_PRIORITY\n );\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* cssChunks mode */\n/* -------------------------------------------------------------------------- */\n\nfunction ensureRelative(p: string): string {\n return p.startsWith(\".\") ? p : \"./\" + p;\n}\n\n/**\n * Per chunk, append a snippet that registers the chunk's emitted CSS file URLs.\n * CSS assets are NOT deleted from the bundle — they stay as cacheable files.\n */\nfunction cssChunksInjection(\n bundle: Rollup.OutputBundle,\n assetsWithCss: Record<string, string[]>,\n globalVarName: string,\n eventName: string\n): void {\n for (const [jsAssetName, cssAssets] of Object.entries(assetsWithCss)) {\n const jsAsset = bundle[jsAssetName] as Rollup.OutputChunk;\n const chunkDir = posix.dirname(jsAsset.fileName);\n const items = cssAssets.map((css) => ({\n id: hash(\"sha1\", css).substring(0, 12),\n rel: ensureRelative(posix.relative(chunkDir, css)),\n }));\n const code = buildLinkRegistrationCode(globalVarName, eventName, items);\n jsAsset.code = buildOutputChunkWithCssInjectionCode(jsAsset.code, code, TOP_EXECUTION_PRIORITY);\n }\n}\n\n/**\n * Remove `.css` entries from a chunk's Vite preload dependency calls so Vite's\n * `__vitePreload` runtime helper never injects them into `document.head` (we link\n * them at the StylesTarget position instead). Drops the CSS indices from each\n * `__vite__mapDeps([...])` call while leaving the (now dead) filename in the\n * shared `m.f=[...]` array — avoids fragile re-indexing.\n */\nfunction stripCssPreloadDeps(code: string): string {\n const arrMatch = code.match(/m\\.f=\\[([^\\]]*)\\]/);\n if (!arrMatch || arrMatch[1] === undefined) {\n return code;\n }\n const entries = [...arrMatch[1].matchAll(/\"((?:[^\"\\\\]|\\\\.)*)\"/g)].map((m) => m[1]);\n const cssIndices = new Set<number>();\n entries.forEach((entry, i) => {\n if (entry !== undefined && entry.endsWith(\".css\")) {\n cssIndices.add(i);\n }\n });\n if (cssIndices.size === 0) {\n return code;\n }\n return code.replace(/__vite__mapDeps\\(\\[([^\\]]*)\\]\\)/g, (_full, inner: string) => {\n const kept = inner\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\" && !cssIndices.has(Number(s)));\n return `__vite__mapDeps([${kept.join(\",\")}])`;\n });\n}\n\n/* -------------------------------------------------------------------------- */\n/* Plugin factory */\n/* -------------------------------------------------------------------------- */\n\nexport function cssInjectionPlugins(options: CssInjectionOptions): Plugin[] {\n const { globalVarName, eventName, mode, jsAssetsFilterFunction } = options;\n // Both per-chunk modes need Vite to emit one CSS file per chunk.\n const perChunk = mode === \"injectPerChunk\" || mode === \"cssChunks\";\n let config: ResolvedConfig;\n\n const plugins: Plugin[] = [\n {\n apply: \"build\",\n enforce: \"post\",\n name: \"vite-plugin-css-position-injection\",\n config(c, env) {\n if (env.command === \"build\" && perChunk) {\n c.build ??= {};\n if (c.build.cssCodeSplit === false) {\n warnLog(\n `[vite-plugin-css-position] Override of 'build.cssCodeSplit' to true; it must be true when mode is '${mode}'.`\n );\n }\n c.build.cssCodeSplit = true;\n }\n },\n configResolved(resolved) {\n config = resolved;\n },\n generateBundle(_opts, bundle) {\n if (config.build.ssr) {\n return;\n }\n\n const cssAssets = Object.keys(bundle).filter((i) => {\n const asset = bundle[i];\n return asset !== undefined && asset.type == \"asset\" && asset.fileName.endsWith(\".css\");\n });\n let unusedCssAssets: string[] = [];\n\n if (mode === \"cssChunks\") {\n // Keep emitted CSS files; register their URLs per chunk. The preload\n // mapDeps stripping happens in a separate order:\"post\" hook below,\n // because Vite resolves the __VITE_PRELOAD__ marker after this hook.\n const assetsWithCss = buildJsCssMap(bundle, jsAssetsFilterFunction);\n cssChunksInjection(bundle, assetsWithCss, globalVarName, eventName);\n // CSS assets and viteMetadata are intentionally kept (manifest stays valid).\n } else {\n const makeInjection = (css: string) =>\n buildInjectionCode(globalVarName, eventName, JSON.stringify(css.trim()));\n if (mode === \"injectPerChunk\") {\n const assetsWithCss = buildJsCssMap(bundle, jsAssetsFilterFunction);\n relativeCssInjection(bundle, assetsWithCss, makeInjection);\n unusedCssAssets = cssAssets.filter((cssAsset) => !!bundle[cssAsset]);\n if (unusedCssAssets.length > 0) {\n warnLog(\n `[vite-plugin-css-position] Some CSS assets were not included in any known JS: ${unusedCssAssets.join(\",\")}`\n );\n }\n } else {\n globalCssInjection(bundle, cssAssets, makeInjection, jsAssetsFilterFunction);\n }\n clearImportedCssViteMetadataFromBundle(bundle, unusedCssAssets);\n }\n\n // Remove the CSS <link> tags Vite injected into the HTML head. In\n // cssChunks mode all entry CSS is handled via registration, so strip all.\n const htmlFiles = Object.keys(bundle).filter((i) => i.endsWith(\".html\"));\n for (const name of htmlFiles) {\n const htmlChunk = bundle[name] as Rollup.OutputAsset;\n let replacedHtml =\n htmlChunk.source instanceof Uint8Array\n ? new TextDecoder().decode(htmlChunk.source)\n : `${htmlChunk.source}`;\n cssAssets.forEach((cssName) => {\n if (!unusedCssAssets.includes(cssName)) {\n replacedHtml = removeLinkStyleSheets(replacedHtml, cssName);\n htmlChunk.source = replacedHtml;\n }\n });\n }\n },\n },\n ];\n\n if (mode === \"cssChunks\") {\n // Runs as order:\"post\" so it executes AFTER Vite's build-import-analysis has\n // resolved __VITE_PRELOAD__ into __vite__mapDeps([...]); only then can we\n // drop the .css indices to stop the preload helper injecting them into <head>.\n plugins.push({\n apply: \"build\",\n enforce: \"post\",\n name: \"vite-plugin-css-position-preload-strip\",\n generateBundle: {\n order: \"post\",\n handler(_opts, bundle) {\n for (const key of Object.keys(bundle)) {\n const chunk = bundle[key];\n if (chunk !== undefined && chunk.type === \"chunk\") {\n chunk.code = stripCssPreloadDeps(chunk.code);\n }\n }\n },\n },\n });\n }\n\n if (options.enableDev) {\n warnLog(\"[vite-plugin-css-position] Experimental dev mode activated!\");\n plugins.push({\n name: \"vite-plugin-css-position-injection-dev\",\n apply: \"serve\",\n enforce: \"post\",\n transform(src, id) {\n if (!isCSSRequest(id)) {\n return;\n }\n const removeStyleCode = buildRemoveStyleCode(globalVarName, eventName, id);\n const injectCode = buildInjectionCode(globalVarName, eventName, \"__vite__css\", {\n type: \"text/css\",\n \"data-vite-dev-id\": id,\n });\n // removeStyleCode runs first since the inject snippet doesn't handle the\n // dev update case on its own.\n let injectionCode = src.replace(\n \"__vite__updateStyle(__vite__id, __vite__css)\",\n \";\\n\" + removeStyleCode + \";\\n\" + injectCode\n );\n injectionCode = injectionCode.replace(\"__vite__removeStyle(__vite__id)\", removeStyleCode);\n return { code: injectionCode, map: null };\n },\n });\n }\n\n return plugins;\n}\n","import type { Plugin, Rollup } from \"vite\";\nimport { randomUUID } from \"crypto\";\nimport { cssInjectionPlugins, type InjectionMode } from \"./cssInjection\";\n\ntype JsAssetsFilterFunction = (chunk: Rollup.OutputChunk) => boolean;\n\n/** How `StylesTarget` includes CSS files in `cssChunks` mode. */\nexport type CssChunksStrategy = \"link\" | \"adopt\";\n\n/** Options shared by every mode. */\ninterface BaseCssPositionOptions {\n instanceId?: string;\n enableDev?: boolean;\n /**\n * Filter function to determine which JS file(s) should receive the CSS injection code.\n * Useful when building multiple entry points and you want CSS only in specific entries.\n * @param chunk - The output chunk being processed\n * @returns true if CSS should be injected into this chunk\n */\n jsAssetsFilterFunction?: JsAssetsFilterFunction;\n}\n\n/**\n * Mode-specific options. A discriminated union so that `cssChunksStrategy` is\n * only assignable when `mode: \"cssChunks\"`, and the deprecated `cssPerChunk` is\n * only assignable for the inline-inject modes.\n */\ntype ModeCssPositionOptions =\n | {\n /**\n * How CSS is delivered and registered:\n * - `\"inject\"` (default): all CSS is concatenated and inlined into the entry\n * JS, registered as `<style>`. The previous default behavior.\n * - `\"injectPerChunk\"`: each chunk's CSS is inlined into its JS, registered\n * as `<style>` — component-level granular lazy-loading via inlined styles.\n *\n * @default \"inject\"\n */\n mode?: \"inject\" | \"injectPerChunk\";\n /**\n * @deprecated Use `mode` instead. `true` maps to `mode: \"injectPerChunk\"`,\n * `false`/unset to `mode: \"inject\"`. Ignored when `mode` is set.\n */\n cssPerChunk?: boolean;\n /** Only valid with `mode: \"cssChunks\"`. */\n cssChunksStrategy?: never;\n }\n | {\n /**\n * `\"cssChunks\"`: Vite's emitted `.css` chunk files are kept; each chunk only\n * registers its CSS file URL, and `StylesTarget` links/adopts it at its\n * position. Closest to standard Vite (cacheable files, lean JS, CSP-friendly).\n */\n mode: \"cssChunks\";\n /**\n * How `StylesTarget` includes the CSS file:\n * - `\"link\"` (default): render `<link rel=\"stylesheet\">`. Simple; may FOUC in\n * Shadow DOM (link is not render-blocking there).\n * - `\"adopt\"`: fetch the CSS and apply it via `adoptedStyleSheets`. No FOUC,\n * CSP-ideal, dedup across roots; requires `fetch` + modern browsers (2023+).\n *\n * @default \"link\"\n */\n cssChunksStrategy?: CssChunksStrategy;\n /** Not applicable in `cssChunks` mode. */\n cssPerChunk?: never;\n };\n\nexport type ViteCustomCssPositionOptions = BaseCssPositionOptions & ModeCssPositionOptions;\n\nfunction resolveMode(options?: ViteCustomCssPositionOptions): InjectionMode {\n if (options?.mode) {\n if (options.cssPerChunk !== undefined) {\n console.warn(\n \"[vite-plugin-css-position] Both 'mode' and the deprecated 'cssPerChunk' are set; 'mode' wins.\"\n );\n }\n return options.mode;\n }\n return options?.cssPerChunk ? \"injectPerChunk\" : \"inject\";\n}\n\nexport default function viteCustomCssPosition(\n options?: ViteCustomCssPositionOptions\n): Plugin | Plugin[] {\n const instanceId =\n options?.instanceId || randomUUID().replace(/-/g, \"\").slice(0, 4);\n\n const globalVarName = `__vcssp_c_${instanceId}`;\n const eventName = `__vcssp_e_${instanceId}`;\n const linkStrategy: CssChunksStrategy = options?.cssChunksStrategy ?? \"link\";\n\n const cssPlugins = cssInjectionPlugins({\n globalVarName,\n eventName,\n enableDev: options?.enableDev ?? false,\n mode: resolveMode(options),\n jsAssetsFilterFunction: options?.jsAssetsFilterFunction,\n });\n\n return [\n {\n name: \"vite-plugin-custom-css-position\",\n config(c) {\n return {\n ...c,\n define: {\n ...c.define,\n __VITE_CSS_POS_GLOBAL_VAR_NAME__: JSON.stringify(globalVarName),\n __VITE_CSS_POS_EVENT_NAME__: JSON.stringify(eventName),\n __VITE_CSS_POS_LINK_STRATEGY__: JSON.stringify(linkStrategy),\n },\n };\n },\n },\n ...cssPlugins,\n ];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["cssSourceCache: Record<string, string>","chunksWithCss: Record<string, string[]>","config: ResolvedConfig","plugins: Plugin[]","unusedCssAssets: string[]","linkStrategy: CssChunksStrategy"],"sources":["../src/cssInjection.ts","../src/viteCustomCssPosition.ts"],"sourcesContent":["/**\n * CSS-by-JS injection core, vendored and trimmed from\n * `vite-plugin-css-injected-by-js` (v3.5.2) by Marco Prontera.\n *\n * Original: https://github.com/marco-prontera/vite-plugin-css-injected-by-js\n * Licensed under the MIT License — Copyright (c) 2023 Marco Prontera.\n *\n * This is a focused port: instead of creating `<style>` elements directly, the\n * generated injection code stores the CSS into a global Map and dispatches an\n * event, which the `StylesTarget` component reacts to in order to render the\n * styles at a custom position (e.g. inside a Shadow DOM). Unlike the original it\n * does NOT run a nested Vite build to produce the injection code; the snippet is\n * built directly and wrapped in an IIFE.\n *\n * Beyond the original's CSS-in-JS modes (`inject`/`injectPerChunk`), this module\n * adds a `cssChunks` mode that keeps Vite's emitted `.css` chunk files and only\n * registers their URLs per chunk, so `StylesTarget` can link/adopt them at its\n * position instead of inlining the CSS.\n */\nimport { hash } from \"crypto\";\nimport { posix } from \"node:path\";\nimport type { Plugin, ResolvedConfig, Rollup } from \"vite\";\n\n/**\n * - `inject`: concatenate all CSS into the entry chunk JS, registered as `<style>`.\n * - `injectPerChunk`: inline each chunk's CSS into its JS, registered as `<style>`.\n * - `cssChunks`: keep emitted `.css` files; register their URLs per chunk so they\n * can be linked/adopted at the `StylesTarget` position.\n */\nexport type InjectionMode = \"inject\" | \"injectPerChunk\" | \"cssChunks\";\n\nexport interface CssInjectionOptions {\n /** Name of the global variable holding the styles Map. */\n globalVarName: string;\n /** Name of the window event dispatched on style updates. */\n eventName: string;\n /** Enable the experimental dev-mode (HMR) transform. */\n enableDev: boolean;\n /** How CSS is delivered and registered. See {@link InjectionMode}. */\n mode: InjectionMode;\n /** Filter which JS chunks receive the CSS injection code. */\n jsAssetsFilterFunction?: ((chunk: Rollup.OutputChunk) => boolean) | undefined;\n}\n\n// CSS is injected before the rest of the chunk's code (parity with the original\n// plugin's default `topExecutionPriority: true`).\nconst TOP_EXECUTION_PRIORITY = true;\n\n// `viteMetadata.importedCss` is a Vite augmentation of Rollup's chunk type that\n// isn't surfaced through Vite's re-exported `Rollup` namespace; access it via a\n// local typed view.\ntype ChunkWithCssMeta = Rollup.OutputChunk & {\n viteMetadata?: { importedCss: Set<string> };\n};\n\nfunction importedCssOf(chunk: Rollup.OutputChunk): Set<string> | undefined {\n return (chunk as ChunkWithCssMeta).viteMetadata?.importedCss;\n}\n\nfunction warnLog(msg: string): void {\n console.warn(`\\x1b[33m \\n${msg} \\x1b[39m`);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Injection code generation */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Build the runtime snippet that registers the given CSS in the global Map and\n * notifies listeners. Wrapped in an IIFE so the local `const`s don't leak into\n * (or collide within) the chunk scope it is appended to.\n *\n * @param cssCodeExpr A JS expression evaluating to the CSS string. In build mode\n * this is a JSON string literal; in dev mode it's the `__vite__css` variable.\n * @param attributes Attributes to attach to the rendered `<style>` (dev only).\n */\nfunction buildInjectionCode(\n globalVarName: string,\n eventName: string,\n cssCodeExpr: string,\n attributes?: Record<string, string>\n): string {\n const attributesString = JSON.stringify(attributes || {});\n const id = `\"${\n attributes?.[\"data-vite-dev-id\"] ?? hash(\"sha1\", cssCodeExpr).substring(0, 12)\n }\"`;\n const body =\n `const css = ${cssCodeExpr};const id = ${id};const attributes = JSON.parse('${attributesString}');` +\n `window.${globalVarName} = window.${globalVarName} || new Map();` +\n `window.${globalVarName}.set(id, {type:\"style\", css, attributes});` +\n `window.dispatchEvent( new Event('${eventName}') );`;\n return `(()=>{${body}})();`;\n}\n\n/**\n * Build the runtime snippet (cssChunks mode) that registers emitted CSS file\n * URLs in the global Map. URLs are resolved relative to the chunk via\n * `import.meta.url`, which is base-agnostic (works for relative and absolute base).\n */\nfunction buildLinkRegistrationCode(\n globalVarName: string,\n eventName: string,\n items: Array<{ id: string; rel: string }>\n): string {\n const data = JSON.stringify(items.map((it) => [it.id, it.rel]));\n return (\n `(()=>{const items=${data};` +\n `window.${globalVarName}=window.${globalVarName}||new Map();` +\n `for(const [id,rel] of items){` +\n `window.${globalVarName}.set(id,{type:\"link\",href:new URL(rel,import.meta.url).href,attributes:{}});}` +\n `window.dispatchEvent(new Event('${eventName}'));})();`\n );\n}\n\n/** Code executed (dev mode) to remove a previously injected style on HMR update. */\nfunction buildRemoveStyleCode(globalVarName: string, eventName: string, id: string): string {\n return `(() => {\n if(window.${globalVarName} && window.${globalVarName}.has('${id}')) {\n window.${globalVarName}.delete('${id}');\n window.dispatchEvent( new Event('${eventName}') );\n }\n })()`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Bundle helpers (ported from vite-plugin-css-injected-by-js utils) */\n/* -------------------------------------------------------------------------- */\n\n// The cache must be global since the execution context differs per entry.\nconst cssSourceCache: Record<string, string> = {};\n\nfunction extractCss(bundle: Rollup.OutputBundle, cssName: string): string {\n const cssAsset = bundle[cssName] as Rollup.OutputAsset | undefined;\n if (cssAsset !== undefined && cssAsset.source) {\n const cssSource = cssAsset.source;\n cssSourceCache[cssName] =\n cssSource instanceof Uint8Array ? new TextDecoder().decode(cssSource) : `${cssSource}`;\n }\n return cssSourceCache[cssName] ?? \"\";\n}\n\nfunction concatCssAndDeleteFromBundle(bundle: Rollup.OutputBundle, cssAssets: string[]): string {\n return cssAssets.reduce((previous, cssName) => {\n const cssSource = extractCss(bundle, cssName);\n delete bundle[cssName];\n return previous + cssSource;\n }, \"\");\n}\n\nfunction isJsOutputChunk(chunk: Rollup.OutputAsset | Rollup.OutputChunk): chunk is Rollup.OutputChunk {\n return chunk.type == \"chunk\" && chunk.fileName.match(/.[cm]?js(?:\\?.+)?$/) != null;\n}\n\nfunction defaultJsAssetsFilter(chunk: Rollup.OutputChunk): boolean {\n return chunk.isEntry && !chunk.fileName.includes(\"polyfill\");\n}\n\nfunction getJsTargetBundleKeys(\n bundle: Rollup.OutputBundle,\n jsAssetsFilterFunction?: (chunk: Rollup.OutputChunk) => boolean\n): string[] {\n if (typeof jsAssetsFilterFunction != \"function\") {\n const jsAssets = Object.keys(bundle).filter((i) => {\n const asset = bundle[i];\n return asset !== undefined && isJsOutputChunk(asset) && defaultJsAssetsFilter(asset);\n });\n const jsTargetFileName = jsAssets[jsAssets.length - 1];\n if (jsTargetFileName === undefined) {\n return [];\n }\n if (jsAssets.length > 1) {\n warnLog(\n `[vite-plugin-css-position] identified \"${jsTargetFileName}\" as one of multiple \"entry\" output files to put the CSS injection code. ` +\n 'If this is not the intended file, use the \"jsAssetsFilterFunction\" option to specify the desired output file.'\n );\n }\n return [jsTargetFileName];\n }\n return Object.entries(bundle)\n .filter(([, chunk]) => isJsOutputChunk(chunk) && jsAssetsFilterFunction(chunk))\n .map(([key]) => key);\n}\n\nfunction buildJsCssMap(\n bundle: Rollup.OutputBundle,\n jsAssetsFilterFunction?: (chunk: Rollup.OutputChunk) => boolean\n): Record<string, string[]> {\n const chunksWithCss: Record<string, string[]> = {};\n const bundleKeys = getJsTargetBundleKeys(\n bundle,\n typeof jsAssetsFilterFunction == \"function\" ? jsAssetsFilterFunction : () => true\n );\n if (bundleKeys.length === 0) {\n throw new Error(\n \"Unable to locate the JavaScript asset for adding the CSS injection code. It is recommended to review your configurations.\"\n );\n }\n for (const key of bundleKeys) {\n const chunk = bundle[key];\n if (chunk === undefined || chunk.type === \"asset\") {\n continue;\n }\n const importedCss = importedCssOf(chunk);\n if (!importedCss || importedCss.size === 0) {\n continue;\n }\n const chunkStyles = chunksWithCss[key] || [];\n chunkStyles.push(...importedCss.values());\n chunksWithCss[key] = chunkStyles;\n }\n return chunksWithCss;\n}\n\nfunction buildOutputChunkWithCssInjectionCode(\n jsAssetCode: string,\n cssInjectionCode: string,\n topExecutionPriorityFlag: boolean\n): string {\n const appCode = jsAssetCode.replace(/\\/\\*\\s*empty css\\s*\\*\\//g, \"\");\n jsAssetCode = topExecutionPriorityFlag ? \"\" : appCode;\n jsAssetCode += cssInjectionCode;\n jsAssetCode += !topExecutionPriorityFlag ? \"\" : appCode;\n return jsAssetCode;\n}\n\nfunction clearImportedCssViteMetadataFromBundle(\n bundle: Rollup.OutputBundle,\n unusedCssAssets: string[]\n): void {\n // Required to exclude removed files from manifest.json\n for (const key in bundle) {\n const chunk = bundle[key];\n if (chunk === undefined || chunk.type !== \"chunk\") {\n continue;\n }\n const meta = (chunk as ChunkWithCssMeta).viteMetadata;\n if (meta && meta.importedCss.size > 0) {\n meta.importedCss.forEach((importedCssFileName: string) => {\n if (!unusedCssAssets.includes(importedCssFileName)) {\n meta.importedCss = new Set();\n }\n });\n }\n }\n}\n\nfunction removeLinkStyleSheets(html: string, cssFileName: string): string {\n const removeCSS = new RegExp(`<link rel=\".*\"[^>]*?href=\".*/?${cssFileName}\"[^>]*?>`);\n return html.replace(removeCSS, \"\");\n}\n\nfunction isCSSRequest(request: string): boolean {\n const CSS_LANGS_RE = /\\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\\?)/;\n return CSS_LANGS_RE.test(request);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Injection modes */\n/* -------------------------------------------------------------------------- */\n\nfunction relativeCssInjection(\n bundle: Rollup.OutputBundle,\n assetsWithCss: Record<string, string[]>,\n makeInjection: (css: string) => string\n): void {\n for (const [jsAssetName, cssAssets] of Object.entries(assetsWithCss)) {\n const assetCss = concatCssAndDeleteFromBundle(bundle, cssAssets);\n const cssInjectionCode = assetCss.length > 0 ? makeInjection(assetCss) : \"\";\n const jsAsset = bundle[jsAssetName] as Rollup.OutputChunk;\n jsAsset.code = buildOutputChunkWithCssInjectionCode(\n jsAsset.code,\n cssInjectionCode,\n TOP_EXECUTION_PRIORITY\n );\n }\n}\n\n// Reuse CSS across sequential builds for the same entry (e.g. multiple formats).\nconst globalCSSCodeEntryCache = new Map<string, string>();\nlet previousFacadeModuleId = \"\";\n\nfunction globalCssInjection(\n bundle: Rollup.OutputBundle,\n cssAssets: string[],\n makeInjection: (css: string) => string,\n jsAssetsFilterFunction: ((chunk: Rollup.OutputChunk) => boolean) | undefined\n): void {\n const jsTargetBundleKeys = getJsTargetBundleKeys(bundle, jsAssetsFilterFunction);\n if (jsTargetBundleKeys.length == 0) {\n throw new Error(\n \"Unable to locate the JavaScript asset for adding the CSS injection code. It is recommended to review your configurations.\"\n );\n }\n const allCssCode = concatCssAndDeleteFromBundle(bundle, cssAssets);\n let cssInjectionCode = allCssCode.length > 0 ? makeInjection(allCssCode) : \"\";\n\n for (const jsTargetKey of jsTargetBundleKeys) {\n const jsAsset = bundle[jsTargetKey] as Rollup.OutputChunk;\n if (jsAsset.facadeModuleId != null && jsAsset.isEntry && cssInjectionCode != \"\") {\n if (jsAsset.facadeModuleId != previousFacadeModuleId) {\n globalCSSCodeEntryCache.clear();\n }\n previousFacadeModuleId = jsAsset.facadeModuleId;\n globalCSSCodeEntryCache.set(jsAsset.facadeModuleId, cssInjectionCode);\n }\n if (\n cssInjectionCode == \"\" &&\n jsAsset.isEntry &&\n jsAsset.facadeModuleId != null &&\n typeof globalCSSCodeEntryCache.get(jsAsset.facadeModuleId) == \"string\"\n ) {\n cssInjectionCode = globalCSSCodeEntryCache.get(jsAsset.facadeModuleId) as string;\n }\n jsAsset.code = buildOutputChunkWithCssInjectionCode(\n jsAsset.code,\n cssInjectionCode,\n TOP_EXECUTION_PRIORITY\n );\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* cssChunks mode */\n/* -------------------------------------------------------------------------- */\n\nfunction ensureRelative(p: string): string {\n return p.startsWith(\".\") ? p : \"./\" + p;\n}\n\n/**\n * Per chunk, append a snippet that registers the chunk's emitted CSS file URLs.\n * CSS assets are NOT deleted from the bundle — they stay as cacheable files.\n */\nfunction cssChunksInjection(\n bundle: Rollup.OutputBundle,\n assetsWithCss: Record<string, string[]>,\n globalVarName: string,\n eventName: string\n): void {\n for (const [jsAssetName, cssAssets] of Object.entries(assetsWithCss)) {\n const jsAsset = bundle[jsAssetName] as Rollup.OutputChunk;\n const chunkDir = posix.dirname(jsAsset.fileName);\n const items = cssAssets.map((css) => ({\n id: hash(\"sha1\", css).substring(0, 12),\n rel: ensureRelative(posix.relative(chunkDir, css)),\n }));\n const code = buildLinkRegistrationCode(globalVarName, eventName, items);\n jsAsset.code = buildOutputChunkWithCssInjectionCode(jsAsset.code, code, TOP_EXECUTION_PRIORITY);\n }\n}\n\n/**\n * Remove `.css` entries from a chunk's Vite preload dependency calls so Vite's\n * `__vitePreload` runtime helper never injects them into `document.head` (we link\n * them at the StylesTarget position instead). Drops the CSS indices from each\n * `__vite__mapDeps([...])` call while leaving the (now dead) filename in the\n * shared `m.f=[...]` array — avoids fragile re-indexing.\n */\nfunction stripCssPreloadDeps(code: string): string {\n const arrMatch = code.match(/m\\.f=\\[([^\\]]*)\\]/);\n if (!arrMatch || arrMatch[1] === undefined) {\n return code;\n }\n const entries = [...arrMatch[1].matchAll(/\"((?:[^\"\\\\]|\\\\.)*)\"/g)].map((m) => m[1]);\n const cssIndices = new Set<number>();\n entries.forEach((entry, i) => {\n if (entry !== undefined && entry.endsWith(\".css\")) {\n cssIndices.add(i);\n }\n });\n if (cssIndices.size === 0) {\n return code;\n }\n return code.replace(/__vite__mapDeps\\(\\[([^\\]]*)\\]\\)/g, (_full, inner: string) => {\n const kept = inner\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\" && !cssIndices.has(Number(s)));\n return `__vite__mapDeps([${kept.join(\",\")}])`;\n });\n}\n\n/* -------------------------------------------------------------------------- */\n/* Plugin factory */\n/* -------------------------------------------------------------------------- */\n\nexport function cssInjectionPlugins(options: CssInjectionOptions): Plugin[] {\n const { globalVarName, eventName, mode, jsAssetsFilterFunction } = options;\n // Both per-chunk modes need Vite to emit one CSS file per chunk.\n const perChunk = mode === \"injectPerChunk\" || mode === \"cssChunks\";\n let config: ResolvedConfig;\n\n const plugins: Plugin[] = [\n {\n apply: \"build\",\n enforce: \"post\",\n name: \"vite-plugin-css-position-injection\",\n config(c, env) {\n if (env.command === \"build\" && perChunk) {\n c.build ??= {};\n if (c.build.cssCodeSplit === false) {\n warnLog(\n `[vite-plugin-css-position] Override of 'build.cssCodeSplit' to true; it must be true when mode is '${mode}'.`\n );\n }\n c.build.cssCodeSplit = true;\n }\n },\n configResolved(resolved) {\n config = resolved;\n },\n generateBundle(_opts, bundle) {\n if (config.build.ssr) {\n return;\n }\n\n const cssAssets = Object.keys(bundle).filter((i) => {\n const asset = bundle[i];\n return asset !== undefined && asset.type == \"asset\" && asset.fileName.endsWith(\".css\");\n });\n let unusedCssAssets: string[] = [];\n\n if (mode === \"cssChunks\") {\n // Keep emitted CSS files; register their URLs per chunk. The preload\n // mapDeps stripping happens in a separate order:\"post\" hook below,\n // because Vite resolves the __VITE_PRELOAD__ marker after this hook.\n const assetsWithCss = buildJsCssMap(bundle, jsAssetsFilterFunction);\n cssChunksInjection(bundle, assetsWithCss, globalVarName, eventName);\n // CSS assets and viteMetadata are intentionally kept (manifest stays valid).\n } else {\n const makeInjection = (css: string) =>\n buildInjectionCode(globalVarName, eventName, JSON.stringify(css.trim()));\n if (mode === \"injectPerChunk\") {\n const assetsWithCss = buildJsCssMap(bundle, jsAssetsFilterFunction);\n relativeCssInjection(bundle, assetsWithCss, makeInjection);\n unusedCssAssets = cssAssets.filter((cssAsset) => !!bundle[cssAsset]);\n if (unusedCssAssets.length > 0) {\n warnLog(\n `[vite-plugin-css-position] Some CSS assets were not included in any known JS: ${unusedCssAssets.join(\",\")}`\n );\n }\n } else {\n globalCssInjection(bundle, cssAssets, makeInjection, jsAssetsFilterFunction);\n }\n clearImportedCssViteMetadataFromBundle(bundle, unusedCssAssets);\n }\n\n // Remove the CSS <link> tags Vite injected into the HTML head. In\n // cssChunks mode all entry CSS is handled via registration, so strip all.\n const htmlFiles = Object.keys(bundle).filter((i) => i.endsWith(\".html\"));\n for (const name of htmlFiles) {\n const htmlChunk = bundle[name] as Rollup.OutputAsset;\n let replacedHtml =\n htmlChunk.source instanceof Uint8Array\n ? new TextDecoder().decode(htmlChunk.source)\n : `${htmlChunk.source}`;\n cssAssets.forEach((cssName) => {\n if (!unusedCssAssets.includes(cssName)) {\n replacedHtml = removeLinkStyleSheets(replacedHtml, cssName);\n htmlChunk.source = replacedHtml;\n }\n });\n }\n },\n },\n ];\n\n if (mode === \"cssChunks\") {\n // Runs as order:\"post\" so it executes AFTER Vite's build-import-analysis has\n // resolved __VITE_PRELOAD__ into __vite__mapDeps([...]); only then can we\n // drop the .css indices to stop the preload helper injecting them into <head>.\n plugins.push({\n apply: \"build\",\n enforce: \"post\",\n name: \"vite-plugin-css-position-preload-strip\",\n generateBundle: {\n order: \"post\",\n handler(_opts, bundle) {\n for (const key of Object.keys(bundle)) {\n const chunk = bundle[key];\n if (chunk !== undefined && chunk.type === \"chunk\") {\n chunk.code = stripCssPreloadDeps(chunk.code);\n }\n }\n },\n },\n });\n }\n\n if (options.enableDev) {\n warnLog(\"[vite-plugin-css-position] Experimental dev mode activated!\");\n plugins.push({\n name: \"vite-plugin-css-position-injection-dev\",\n apply: \"serve\",\n enforce: \"post\",\n transform(src, id) {\n if (!isCSSRequest(id)) {\n return;\n }\n const removeStyleCode = buildRemoveStyleCode(globalVarName, eventName, id);\n const injectCode = buildInjectionCode(globalVarName, eventName, \"__vite__css\", {\n type: \"text/css\",\n \"data-vite-dev-id\": id,\n });\n // removeStyleCode runs first since the inject snippet doesn't handle the\n // dev update case on its own.\n let injectionCode = src.replace(\n \"__vite__updateStyle(__vite__id, __vite__css)\",\n \";\\n\" + removeStyleCode + \";\\n\" + injectCode\n );\n injectionCode = injectionCode.replace(\"__vite__removeStyle(__vite__id)\", removeStyleCode);\n return { code: injectionCode, map: null };\n },\n });\n }\n\n return plugins;\n}\n","import type { Plugin, Rollup } from \"vite\";\nimport { randomUUID } from \"crypto\";\nimport { cssInjectionPlugins } from \"./cssInjection\";\n\ntype JsAssetsFilterFunction = (chunk: Rollup.OutputChunk) => boolean;\n\n/** How `StylesTarget` includes CSS files in `cssChunks` mode. */\nexport type CssChunksStrategy = \"link\" | \"adopt\";\n\n/** Options shared by every mode. */\ninterface BaseCssPositionOptions {\n instanceId?: string;\n enableDev?: boolean;\n /**\n * Filter function to determine which JS file(s) should receive the CSS injection code.\n * Useful when building multiple entry points and you want CSS only in specific entries.\n * @param chunk - The output chunk being processed\n * @returns true if CSS should be injected into this chunk\n */\n jsAssetsFilterFunction?: JsAssetsFilterFunction;\n}\n\n/**\n * Mode-specific options. A discriminated union so that `cssChunksStrategy` is\n * only assignable when `mode: \"cssChunks\"`.\n */\ntype ModeCssPositionOptions =\n | {\n /**\n * How CSS is delivered and registered:\n * - `\"inject\"` (default): all CSS is concatenated and inlined into the entry\n * JS, registered as `<style>`. The previous default behavior.\n * - `\"injectPerChunk\"`: each chunk's CSS is inlined into its JS, registered\n * as `<style>` — component-level granular lazy-loading via inlined styles.\n *\n * @default \"inject\"\n */\n mode?: \"inject\" | \"injectPerChunk\";\n /** Only valid with `mode: \"cssChunks\"`. */\n cssChunksStrategy?: never;\n }\n | {\n /**\n * `\"cssChunks\"`: Vite's emitted `.css` chunk files are kept; each chunk only\n * registers its CSS file URL, and `StylesTarget` links/adopts it at its\n * position. Closest to standard Vite (cacheable files, lean JS, CSP-friendly).\n */\n mode: \"cssChunks\";\n /**\n * How `StylesTarget` includes the CSS file:\n * - `\"link\"` (default): render `<link rel=\"stylesheet\">`. Simple; may FOUC in\n * Shadow DOM (link is not render-blocking there).\n * - `\"adopt\"`: fetch the CSS and apply it via `adoptedStyleSheets`. No FOUC,\n * CSP-ideal, dedup across roots; requires `fetch` + modern browsers (2023+).\n *\n * @default \"link\"\n */\n cssChunksStrategy?: CssChunksStrategy;\n };\n\nexport type ViteCustomCssPositionOptions = BaseCssPositionOptions & ModeCssPositionOptions;\n\nexport default function viteCustomCssPosition(\n options?: ViteCustomCssPositionOptions\n): Plugin | Plugin[] {\n const instanceId =\n options?.instanceId || randomUUID().replace(/-/g, \"\").slice(0, 4);\n\n const globalVarName = `__vcssp_c_${instanceId}`;\n const eventName = `__vcssp_e_${instanceId}`;\n const linkStrategy: CssChunksStrategy = options?.cssChunksStrategy ?? \"link\";\n\n const cssPlugins = cssInjectionPlugins({\n globalVarName,\n eventName,\n enableDev: options?.enableDev ?? false,\n mode: options?.mode ?? \"inject\",\n jsAssetsFilterFunction: options?.jsAssetsFilterFunction,\n });\n\n return [\n {\n name: \"vite-plugin-custom-css-position\",\n config(c) {\n return {\n ...c,\n define: {\n ...c.define,\n __VITE_CSS_POS_GLOBAL_VAR_NAME__: JSON.stringify(globalVarName),\n __VITE_CSS_POS_EVENT_NAME__: JSON.stringify(eventName),\n __VITE_CSS_POS_LINK_STRATEGY__: JSON.stringify(linkStrategy),\n },\n };\n },\n },\n ...cssPlugins,\n ];\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-css-position",
3
- "version": "3.0.0-next.1",
3
+ "version": "3.0.0-next.2",
4
4
  "description": "Custom position of vite styles within a vite react app",
5
5
  "type": "module",
6
6
  "license": "MIT",