1- import {
2- IndexHtmlTransformContext ,
3- IndexHtmlTransformResult ,
4- Plugin ,
5- } from 'vite' ;
1+ import { Plugin } from 'vite' ;
2+ import { OutputAsset , OutputChunk } from 'rollup' ;
3+ import { buildCSSInjectionCode , removeLinkStyleSheets } from './utils' ;
64
75/**
86 * Inject the CSS compiled with JS.
97 *
108 * @return {Plugin }
119 */
12- function cssInjectedByJsPlugin (
10+ export default function cssInjectedByJsPlugin (
1311 { topExecutionPriority, styleId } = {
1412 topExecutionPriority : true ,
1513 styleId : '' ,
@@ -22,87 +20,41 @@ function cssInjectedByJsPlugin(
2220 apply : 'build' ,
2321 enforce : 'post' ,
2422 name : 'css-in-js-plugin' ,
25- generateBundle ( opts , bundle ) {
26- let styleCode = '' ;
27-
28- for ( const key in bundle ) {
29- if ( bundle [ key ] ) {
30- const chunk = bundle [ key ] ;
31-
32- if (
33- chunk . type === 'asset' &&
34- chunk . fileName . includes ( '.css' )
35- ) {
36- styleCode += chunk . source ;
37- delete bundle [ key ] ;
38- }
23+ async generateBundle ( opts , bundle ) {
24+ const htmlFiles = Object . keys ( bundle ) . filter ( ( i ) => i . endsWith ( '.html' ) ) ;
25+ const cssAssets = Object . keys ( bundle ) . filter ( ( i ) => bundle [ i ] . type == 'asset' && bundle [ i ] . fileName . endsWith ( '.css' ) ) ;
26+ const jsAssets = Object . keys ( bundle ) . filter (
27+ ( i ) =>
28+ bundle [ i ] . type == 'chunk' &&
29+ bundle [ i ] . fileName . match ( / .[ c m ] ? j s $ / ) != null &&
30+ ! bundle [ i ] . fileName . includes ( 'polyfill' )
31+ ) ;
32+
33+ for ( const name of htmlFiles ) {
34+ const htmlChunk = bundle [ name ] as OutputAsset ;
35+ let replacedHtml = htmlChunk . source as string ;
36+
37+ const allCssCode = cssAssets . reduce ( function extractCssCodeAndDeleteFromBundle ( previousValue , cssName ) {
38+ const cssAsset = bundle [ cssName ] as OutputAsset ;
39+ const result = previousValue + cssAsset . source ;
40+ delete bundle [ cssName ] ;
41+ replacedHtml = removeLinkStyleSheets ( replacedHtml , cssName ) ;
42+ htmlChunk . source = replacedHtml ;
43+ return result ;
44+ } , '' ) ;
45+
46+ if ( allCssCode . length > 0 ) {
47+ cssToInject = allCssCode ;
3948 }
4049 }
4150
42- if ( styleCode . length > 0 ) {
43- cssToInject = styleCode ;
44- }
45-
46- for ( const key in bundle ) {
47- if ( bundle [ key ] ) {
48- const chunk = bundle [ key ] ;
51+ const jsAsset = bundle [ jsAssets [ 0 ] ] as OutputChunk ;
4952
50- if (
51- chunk . type === 'chunk' &&
52- chunk . fileName . match ( / .[ c m ] ? j s $ / ) != null &&
53- ! chunk . fileName . includes ( 'polyfill' )
54- ) {
55- let topCode : string = '' ;
56- let bottomCode : string = '' ;
57- if ( topExecutionPriority ) {
58- bottomCode = chunk . code ;
59- } else {
60- topCode = chunk . code ;
61- }
62-
63- chunk . code = topCode ;
64- chunk . code +=
65- "(function(){ try {var elementStyle = document.createElement('style'); elementStyle.appendChild(document.createTextNode(" ;
66- chunk . code += JSON . stringify ( cssToInject . trim ( ) ) ;
67- chunk . code += ')); ' ;
68- if ( typeof styleId == 'string' && styleId . length > 0 ) {
69- chunk . code += ` elementStyle.id = "${ styleId } "; ` ;
70- }
71- chunk . code +=
72- "document.head.appendChild(elementStyle);} catch(e) {console.error('vite-plugin-css-injected-by-js', e);} })();" ;
73- chunk . code += bottomCode ;
74-
75- break ;
76- }
77- }
78- }
79- } ,
80- transformIndexHtml : {
81- enforce : 'post' ,
82- transform (
83- html : string ,
84- ctx ?: IndexHtmlTransformContext
85- ) : IndexHtmlTransformResult {
86- if ( ! ctx || ! ctx . bundle ) return html ;
87-
88- for ( const [ , value ] of Object . entries ( ctx . bundle ) ) {
89- if ( value . fileName . endsWith ( '.css' ) ) {
90- // Remove CSS link from HTML generated.
91- const reCSS = new RegExp (
92- `<link rel="stylesheet"[^>]*?href=".*/${ value . fileName } "[^>]*?>`
93- ) ;
94- html = html . replace ( reCSS , '' ) ;
95- }
96- }
97-
98- return html ;
99- } ,
53+ const cssInjectionCode = await buildCSSInjectionCode ( cssToInject , styleId ) ;
54+ const appCode = jsAsset . code ;
55+ jsAsset . code = topExecutionPriority ? '' : appCode ;
56+ jsAsset . code += cssInjectionCode ? cssInjectionCode . code : '' ;
57+ jsAsset . code += ! topExecutionPriority ? '' : appCode ;
10058 } ,
10159 } ;
10260}
103-
104- module . exports = cssInjectedByJsPlugin ;
105-
106- cssInjectedByJsPlugin . default = cssInjectedByJsPlugin ;
107-
108- export default cssInjectedByJsPlugin ;
0 commit comments