@@ -145,22 +145,12 @@ module.exports = function (browserify, options) {
145145 } ) ;
146146
147147 // create a loader for this entry file
148- if ( ! loadersByFile [ cssOutFilename ] ) {
149- loadersByFile [ cssOutFilename ] = new FileSystemLoader ( rootDir , plugins ) ;
148+ var loader = loadersByFile [ cssOutFilename ] ;
149+ if ( ! loader ) {
150+ loader = loadersByFile [ cssOutFilename ] = new FileSystemLoader ( rootDir , plugins ) ;
150151 }
151152
152- // TODO: clean this up so there's less scope crossing
153- Cmify . prototype . _flush = function ( callback ) {
154- var self = this ;
155- var filename = this . _filename ;
156-
157- // only handle .css files
158- if ( ! this . isCssFile ( filename ) ) { return callback ( ) ; }
159-
160- // grab the correct loader
161- var loader = loadersByFile [ this . _cssOutFilename ] ;
162-
163- // convert css to js before pushing
153+ function createCssModuleSource ( filename , cb ) {
164154 // reset the `tokensByFile` cache
165155 var relFilename = path . relative ( rootDir , filename ) ;
166156 tokensByFile [ filename ] = loader . tokensByFile [ filename ] = null ;
@@ -188,11 +178,28 @@ module.exports = function (browserify, options) {
188178
189179 assign ( tokensByFile , loader . tokensByFile ) ;
190180
191- self . push ( output . join ( '\n' ) ) ;
192- return callback ( ) ;
181+ return cb ( null , output . join ( '\n' ) ) ;
193182 } ) . catch ( function ( err ) {
194- self . push ( 'console.error("' + err + '");' ) ;
195- self . emit ( 'error' , err ) ;
183+ return cb ( err ) ;
184+ } ) ;
185+ }
186+
187+ // TODO: clean this up so there's less scope crossing
188+ Cmify . prototype . _flush = function ( callback ) {
189+ var self = this ;
190+ var filename = this . _filename ;
191+
192+ // only handle .css files
193+ if ( ! this . isCssFile ( filename ) ) { return callback ( ) ; }
194+
195+ createCssModuleSource ( filename , function ( err , source ) {
196+ if ( err ) {
197+ self . push ( 'console.error("' + err + '");' ) ;
198+ self . emit ( 'error' , err ) ;
199+ return callback ( ) ;
200+ }
201+
202+ self . push ( source ) ;
196203 return callback ( ) ;
197204 } ) ;
198205 } ;
@@ -201,7 +208,48 @@ module.exports = function (browserify, options) {
201208
202209 // ----
203210
211+ function invalidateFile ( filename ) {
212+ Object . keys ( loadersByFile ) . forEach ( function ( loaderKey ) {
213+ var loader = loadersByFile [ loaderKey ] ;
214+
215+ // clear the token cache for the changed file
216+ tokensByFile [ filename ] = loader . tokensByFile [ filename ] = null ;
217+
218+ // also clear the cache for any modules depending on this one
219+ try {
220+ var deps = loader . deps . dependantsOf ( filename ) ;
221+ deps . forEach ( function ( dep ) {
222+ tokensByFile [ dep ] = loader . tokensByFile [ dep ] = null ;
223+ } ) ;
224+ }
225+ catch ( err ) { }
226+ } ) ;
227+ }
228+
204229 function addHooks ( ) {
230+ browserify . pipeline . get ( 'deps' ) . push ( through . obj ( function write ( row , enc , next ) {
231+ // css modules need to be regenerated at this point
232+ // (so that imported @value updates are carried through hmr)
233+ var self = this ;
234+ if ( ! / \. c s s $ / . test ( row . id ) ) {
235+ return next ( null , row )
236+ }
237+
238+ invalidateFile ( row . id )
239+ return createCssModuleSource ( row . id , function ( err , source ) {
240+ if ( err ) {
241+ row . source = 'console.error("' + err + '");' ;
242+ self . emit ( 'error' , err ) ;
243+ return next ( null , row )
244+ }
245+
246+ row . source = source
247+ next ( null , row )
248+ } )
249+ } , function end ( done ) {
250+ done ( ) ;
251+ } ) ) ;
252+
205253 browserify . pipeline . get ( 'pack' ) . push ( through ( function write ( row , enc , next ) {
206254 next ( null , row )
207255 } , function end ( cb ) {
@@ -241,6 +289,11 @@ module.exports = function (browserify, options) {
241289 browserify . on ( 'reset' , addHooks ) ;
242290 addHooks ( ) ;
243291
292+ browserify . on ( 'update' , function ( files ) {
293+ // invalidate cache of any changed css modules
294+ files . forEach ( invalidateFile ) ;
295+ } )
296+
244297 return browserify ;
245298} ;
246299
0 commit comments