@@ -13,18 +13,25 @@ import { version } from './getVersion.js'
1313import { template } from './getTemplate.js'
1414import { bufferToDataURL } from "./dataurl.js"
1515import { kB } from "./kB.js"
16- import { getInnerOptions , Options , innerOptions , HtmlMinifierOptions } from "./options.js"
16+ import { getInnerOptions , Options , InnerOptions as InnerOptions , HtmlMinifierOptions , defaultHtmlMinifierTerserOptions } from "./options.js"
1717import { cutPrefix } from "./cutPrefix.js"
1818import { CompressFormat , CompressFormatAlias , Compressor } from "./compress.js"
1919
2020export function singleFileCompression ( opt ?: Options ) : PluginOption {
2121 let conf : ResolvedConfig
22+ const innerOptions = getInnerOptions ( opt )
2223 return {
2324 name : "singleFileCompression" ,
2425 enforce : "post" ,
25- config : setConfig ,
26- configResolved ( c ) { conf = c } ,
27- generateBundle : ( _ , bundle ) => generateBundle ( bundle , conf , getInnerOptions ( opt ) ) ,
26+ config ( ...args ) {
27+ return setConfig . call ( this , innerOptions , ...args )
28+ } ,
29+ configResolved ( c ) {
30+ conf = c
31+ } ,
32+ generateBundle ( outputOptions , bundle ) {
33+ return generateBundle ( bundle , conf , innerOptions )
34+ } ,
2835 }
2936}
3037
@@ -36,18 +43,17 @@ export {
3643 CompressFormat ,
3744 CompressFormatAlias ,
3845 Compressor ,
46+ defaultHtmlMinifierTerserOptions ,
3947}
4048
41- function setConfig ( this : ConfigPluginContext , config : UserConfig , env : ConfigEnv ) {
49+ function setConfig ( this : ConfigPluginContext , opt : InnerOptions , config : UserConfig , env : ConfigEnv ) {
4250 config . base ??= './'
4351
4452 const build = ( config . build ??= { } )
4553
4654 build . cssCodeSplit ??= false
4755 build . assetsInlineLimit ??= ( ) => true
48- build . chunkSizeWarningLimit ??= Number . MAX_SAFE_INTEGER
4956 build . modulePreload ?? build . polyfillModulePreload ?? ( build . modulePreload = { polyfill : false } )
50- build . reportCompressedSize ??= false
5157
5258 if ( this . meta . rolldownVersion ) {
5359 // Vite 8
@@ -66,8 +72,13 @@ function setConfig(this: ConfigPluginContext, config: UserConfig, env: ConfigEnv
6672 }
6773}
6874
69- async function generateBundle ( bundle : OutputBundle , config : ResolvedConfig , options : innerOptions ) {
70- console . log ( pc . reset ( '\n\n' ) + pc . cyan ( 'vite-plugin-singlefile-compression ' + version ) + ' ' + pc . green ( options . compressFormat ) )
75+ async function generateBundle ( bundle : OutputBundle , config : ResolvedConfig , options : InnerOptions ) {
76+ console . log (
77+ pc . reset ( '\n\n' ) +
78+ pc . cyan ( 'vite-plugin-singlefile-compression ' + version ) +
79+ ' ' +
80+ ( options . enableCompress ? pc . green ( options . compressFormat ) : pc . red ( 'disable compress' ) )
81+ )
7182
7283 // rename
7384 if ( options . rename
@@ -113,7 +124,7 @@ async function generateBundle(bundle: OutputBundle, config: ResolvedConfig, opti
113124 for ( const name in bundle ) {
114125 if ( name . startsWith ( assetsDir ) )
115126 bundleAssetsNames . push ( name )
116- else if ( name . endsWith ( '. html' ) )
127+ else if ( / \. h t m l $ / i . test ( name ) )
117128 bundleHTMLNames . push ( name )
118129 }
119130
@@ -136,6 +147,7 @@ async function generateBundle(bundle: OutputBundle, config: ResolvedConfig, opti
136147 if ( scriptElement ) {
137148 scriptElement . remove ( )
138149 scriptElement . removeAttribute ( 'src' )
150+ scriptElement . removeAttribute ( 'crossorigin' )
139151 scriptElement . innerHTML = fakeScript
140152 document . body . appendChild ( scriptElement )
141153 } else {
@@ -144,7 +156,8 @@ async function generateBundle(bundle: OutputBundle, config: ResolvedConfig, opti
144156
145157 // get css tag
146158 let allCSS = ''
147- for ( const element of document . querySelectorAll < HTMLLinkElement > ( `link[rel=stylesheet]${ assetsHrefSelector } ` ) ) {
159+ const linkStylesheet = document . querySelectorAll < HTMLLinkElement > ( `link[rel=stylesheet]${ assetsHrefSelector } ` )
160+ for ( const element of linkStylesheet ) {
148161 const name = cutPrefix ( element . href , config . base )
149162 thisDel . add ( name )
150163 const css = bundle [ name ] as OutputAsset
@@ -157,35 +170,54 @@ async function generateBundle(bundle: OutputBundle, config: ResolvedConfig, opti
157170 globalDoNotDelete . add ( name )
158171 }
159172 // add script for load css
160- allCSS += cssSource . replace ( / \n $ / , '' )
173+ allCSS += cssSource . replace ( / ( \/ \* [ ^ * ] * \* \/ ) ? \s * $ / , '' )
161174 }
162175 // remove tag
163- element . remove ( )
176+ if ( options . enableCompress )
177+ element . remove ( )
178+ }
179+ if ( allCSS ) {
180+ if ( options . enableCompress ) {
181+ newJSCode . push ( template . css ( allCSS ) )
182+ } else {
183+ const e = document . createElement ( 'style' )
184+ e . innerHTML = allCSS
185+ linkStylesheet [ 0 ] . before ( e )
186+ for ( const e of linkStylesheet ) {
187+ e . remove ( )
188+ }
189+ }
164190 }
165- newJSCode . push ( template . css ( allCSS ) )
166191
167192 // inline html assets
168193 const assetsDataURL = { } as { [ key : string ] : string }
169194 if ( options . tryInlineHtmlAssets ) {
170- for ( const element of ( document . querySelectorAll ( assetsSrcSelector ) as NodeListOf < HTMLImageElement > ) ) {
195+ for ( const element of document . querySelectorAll < HTMLImageElement > ( assetsSrcSelector ) ) {
171196 const name = cutPrefix ( element . src , assetsDirWithBase )
172- if ( name . endsWith ( '.js' ) )
197+ if ( / \. j s $ / i . test ( name ) )
173198 continue
174- if ( ! Object . prototype . hasOwnProperty . call ( assetsDataURL , name ) ) {
199+ if ( ! options . enableCompress || ! Object . prototype . hasOwnProperty . call ( assetsDataURL , name ) ) {
175200 const bundleName = assetsDir + name
176201 const a = bundle [ bundleName ] as OutputAsset
177202 if ( ! a )
178203 continue
179204 thisDel . add ( bundleName )
180205 oldSize += a . source . length
181- if ( ! Object . prototype . hasOwnProperty . call ( globalAssetsDataURL , name ) )
182- globalAssetsDataURL [ name ] = bufferToDataURL ( name , Buffer . from (
183- //@ts -ignore
184- a . source
185- ) )
186- assetsDataURL [ name ] = globalAssetsDataURL [ name ]
206+ let dataURL : string
207+ if ( Object . prototype . hasOwnProperty . call ( globalAssetsDataURL , name ) ) {
208+ dataURL = globalAssetsDataURL [ name ]
209+ } else {
210+ globalAssetsDataURL [ name ] = dataURL = bufferToDataURL ( name , Buffer . from ( a . source ) )
211+ }
212+ if ( options . enableCompress ) {
213+ assetsDataURL [ name ] = dataURL
214+ } else {
215+ element . src = dataURL
216+ }
217+ }
218+ if ( options . enableCompress ) {
219+ element . src = `data:${ name } `
187220 }
188- element . src = `data:${ name } `
189221 }
190222 }
191223
@@ -225,10 +257,20 @@ async function generateBundle(bundle: OutputBundle, config: ResolvedConfig, opti
225257 }
226258 const { dataURL, size } = globalPublicFilesCache [ iconName ]
227259 oldSize += size
228- newJSCode . push ( template . icon ( dataURL ) )
229- if ( ! element ) {
230- // add link icon tag
231- document . head . insertAdjacentHTML ( 'beforeend' , '<link rel="icon" href="data:">' )
260+ if ( options . enableCompress ) {
261+ newJSCode . push ( template . icon ( dataURL ) )
262+ if ( ! element ) {
263+ // add link icon tag
264+ document . head . insertAdjacentHTML ( 'beforeend' , '<link rel="icon" href="data:">' )
265+ }
266+ } else {
267+ if ( element ) {
268+ element . href = dataURL
269+ } else {
270+ const e = document . head . appendChild ( document . createElement ( 'link' ) )
271+ e . rel = 'icon'
272+ e . href = dataURL
273+ }
232274 }
233275 } catch ( e ) {
234276 if ( element ) console . error ( e )
@@ -280,9 +322,14 @@ async function generateBundle(bundle: OutputBundle, config: ResolvedConfig, opti
280322 inlineHtmlAssets ( )
281323 }
282324
283- htmlChunk . source = htmlChunk . source . split ( fakeScript , 2 ) . join (
284- template . base ( newJSCode . join ( ';' ) , options . compressFormat , options . useBase128 , options . compressor )
285- )
325+ let outputScript = newJSCode . join ( ';' )
326+ if ( options . enableCompress ) {
327+ outputScript = template . base ( outputScript , options . compressFormat , options . useBase128 , options . compressor )
328+ } else {
329+ outputScript = outputScript . replaceAll ( '</script' , '<\\/script' )
330+ }
331+
332+ htmlChunk . source = htmlChunk . source . split ( fakeScript , 2 ) . join ( outputScript )
286333
287334 // log
288335 console . log ( " " + pc . gray ( kB ( oldSize ) + " -> " ) + pc . cyanBright ( kB ( htmlChunk . source . length ) ) + '\n' )
0 commit comments