@@ -145,22 +145,12 @@ module.exports = function (browserify, options) {
145
145
} ) ;
146
146
147
147
// 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 ) ;
150
151
}
151
152
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 ) {
164
154
// reset the `tokensByFile` cache
165
155
var relFilename = path . relative ( rootDir , filename ) ;
166
156
tokensByFile [ filename ] = loader . tokensByFile [ filename ] = null ;
@@ -188,11 +178,28 @@ module.exports = function (browserify, options) {
188
178
189
179
assign ( tokensByFile , loader . tokensByFile ) ;
190
180
191
- self . push ( output . join ( '\n' ) ) ;
192
- return callback ( ) ;
181
+ return cb ( null , output . join ( '\n' ) ) ;
193
182
} ) . 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 ) ;
196
203
return callback ( ) ;
197
204
} ) ;
198
205
} ;
@@ -201,7 +208,48 @@ module.exports = function (browserify, options) {
201
208
202
209
// ----
203
210
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
+
204
229
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
+
205
253
browserify . pipeline . get ( 'pack' ) . push ( through ( function write ( row , enc , next ) {
206
254
next ( null , row )
207
255
} , function end ( cb ) {
@@ -241,6 +289,11 @@ module.exports = function (browserify, options) {
241
289
browserify . on ( 'reset' , addHooks ) ;
242
290
addHooks ( ) ;
243
291
292
+ browserify . on ( 'update' , function ( files ) {
293
+ // invalidate cache of any changed css modules
294
+ files . forEach ( invalidateFile ) ;
295
+ } )
296
+
244
297
return browserify ;
245
298
} ;
246
299
0 commit comments