@@ -237,7 +237,6 @@ const cssUrlAssetRE = /__VITE_CSS_URL__([\da-f]+)__/g
237237 */
238238export function cssPlugin ( config : ResolvedConfig ) : Plugin {
239239 const isBuild = config . command === 'build'
240- let server : ViteDevServer
241240 let moduleCache : Map < string , Record < string , string > >
242241
243242 const resolveUrl = config . createResolver ( {
@@ -254,10 +253,6 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
254253 return {
255254 name : 'vite:css' ,
256255
257- configureServer ( _server ) {
258- server = _server
259- } ,
260-
261256 buildStart ( ) {
262257 // Ensure a new cache for every build (i.e. rebuilding in watch mode)
263258 moduleCache = new Map < string , Record < string , string > > ( )
@@ -292,16 +287,14 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
292287 }
293288 } ,
294289
295- async transform ( raw , id , options ) {
290+ async transform ( raw , id ) {
296291 if (
297292 ! isCSSRequest ( id ) ||
298293 commonjsProxyRE . test ( id ) ||
299294 SPECIAL_QUERY_RE . test ( id )
300295 ) {
301296 return
302297 }
303- const ssr = options ?. ssr === true
304-
305298 const urlReplacer : CssUrlReplacer = async ( url , importer ) => {
306299 const decodedUrl = decodeURI ( url )
307300 if ( checkPublicFile ( decodedUrl , config ) ) {
@@ -345,60 +338,12 @@ export function cssPlugin(config: ResolvedConfig): Plugin {
345338 moduleCache . set ( id , modules )
346339 }
347340
348- // track deps for build watch mode
349- if ( config . command === 'build' && config . build . watch && deps ) {
341+ if ( deps ) {
350342 for ( const file of deps ) {
351343 this . addWatchFile ( file )
352344 }
353345 }
354346
355- // dev
356- if ( server ) {
357- // server only logic for handling CSS @import dependency hmr
358- const { moduleGraph } = server
359- const thisModule = moduleGraph . getModuleById ( id )
360- if ( thisModule ) {
361- // CSS modules cannot self-accept since it exports values
362- const isSelfAccepting =
363- ! modules && ! inlineRE . test ( id ) && ! htmlProxyRE . test ( id )
364- if ( deps ) {
365- // record deps in the module graph so edits to @import css can trigger
366- // main import to hot update
367- const depModules = new Set < string | ModuleNode > ( )
368- const devBase = config . base
369- for ( const file of deps ) {
370- depModules . add (
371- isCSSRequest ( file )
372- ? moduleGraph . createFileOnlyEntry ( file )
373- : await moduleGraph . ensureEntryFromUrl (
374- stripBase (
375- await fileToUrl ( file , config , this ) ,
376- ( config . server ?. origin ?? '' ) + devBase ,
377- ) ,
378- ssr ,
379- ) ,
380- )
381- }
382- moduleGraph . updateModuleInfo (
383- thisModule ,
384- depModules ,
385- null ,
386- // The root CSS proxy module is self-accepting and should not
387- // have an explicit accept list
388- new Set ( ) ,
389- null ,
390- isSelfAccepting ,
391- ssr ,
392- )
393- for ( const file of deps ) {
394- this . addWatchFile ( file )
395- }
396- } else {
397- thisModule . isSelfAccepting = isSelfAccepting
398- }
399- }
400- }
401-
402347 return {
403348 code : css ,
404349 map,
@@ -945,6 +890,78 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
945890 }
946891}
947892
893+ export function cssAnalysisPlugin ( config : ResolvedConfig ) : Plugin {
894+ let server : ViteDevServer
895+
896+ return {
897+ name : 'vite:css-analysis' ,
898+
899+ configureServer ( _server ) {
900+ server = _server
901+ } ,
902+
903+ async transform ( _ , id , options ) {
904+ if (
905+ ! isCSSRequest ( id ) ||
906+ commonjsProxyRE . test ( id ) ||
907+ SPECIAL_QUERY_RE . test ( id )
908+ ) {
909+ return
910+ }
911+
912+ const ssr = options ?. ssr === true
913+ const { moduleGraph } = server
914+ const thisModule = moduleGraph . getModuleById ( id )
915+
916+ // Handle CSS @import dependency HMR and other added modules via this.addWatchFile.
917+ // JS-related HMR is handled in the import-analysis plugin.
918+ if ( thisModule ) {
919+ // CSS modules cannot self-accept since it exports values
920+ const isSelfAccepting =
921+ ! cssModulesCache . get ( config ) ?. get ( id ) &&
922+ ! inlineRE . test ( id ) &&
923+ ! htmlProxyRE . test ( id )
924+ // attached by pluginContainer.addWatchFile
925+ const pluginImports = ( this as any ) . _addedImports as
926+ | Set < string >
927+ | undefined
928+ if ( pluginImports ) {
929+ // record deps in the module graph so edits to @import css can trigger
930+ // main import to hot update
931+ const depModules = new Set < string | ModuleNode > ( )
932+ const devBase = config . base
933+ for ( const file of pluginImports ) {
934+ depModules . add (
935+ isCSSRequest ( file )
936+ ? moduleGraph . createFileOnlyEntry ( file )
937+ : await moduleGraph . ensureEntryFromUrl (
938+ stripBase (
939+ await fileToUrl ( file , config , this ) ,
940+ ( config . server ?. origin ?? '' ) + devBase ,
941+ ) ,
942+ ssr ,
943+ ) ,
944+ )
945+ }
946+ moduleGraph . updateModuleInfo (
947+ thisModule ,
948+ depModules ,
949+ null ,
950+ // The root CSS proxy module is self-accepting and should not
951+ // have an explicit accept list
952+ new Set ( ) ,
953+ null ,
954+ isSelfAccepting ,
955+ ssr ,
956+ )
957+ } else {
958+ thisModule . isSelfAccepting = isSelfAccepting
959+ }
960+ }
961+ } ,
962+ }
963+ }
964+
948965/**
949966 * Create a replacer function that takes code and replaces given pure CSS chunk imports
950967 * @param pureCssChunkNames The chunks that only contain pure CSS and should be replaced
0 commit comments