browserify / watchify

watch mode for browserify builds
Other
1.79k stars 203 forks source link

bundler.reload()? #63

Closed max-degterev closed 10 years ago

max-degterev commented 10 years ago

Hi!

I'm using watchify with the jadeify transform. Everything works like a charm, but browserify cannot follow includes inside jade templates. So if one of the included templates is changed, it doesn't reload the bundle, nor will it if I call bundler.bundle() manually because the main template haven't changed.

Currently I have a watcher on all jade files, and then re-create watchify bundle:

compileJavascripts = (src, options)->
  bundler.close?() if bundler
  args = [src, extensions: ['.coffee', '.jade']]
  bundler = if options.watch then watchify(args...) else browserify(args...)

That's not good and calling .close() at that point is already too late because bundle might have had that jade template watched and is already in the process of recompilation.

It would be really nice to have a method that would just force watchify to clear caches and reload every watched file. Is there something like that, or am I doing something wrong?

A bit more code to understand what's happening:

BROWSERIFY_RATELIMIT = 1000
bundler = null # for watchify to avoid memory leaks
lastBrowserified = 0

compileJavascripts = (src, options)->
  bundler.close?() if bundler
  args = [src, extensions: ['.coffee', '.jade']]
  bundler = if options.watch then watchify(args...) else browserify(args...)

  for alias in getAliases()
    [realPath, relativePath] = alias.split(':')
    bundler.require(realPath, expose: relativePath)

  bundler.require(key) for key of pkg['browserify-shim']
  bundler.transform(transform) for transform in JS_TRANSFORMS

  compile = (files)->
    startTime = Date.now()
    return if startTime - lastBrowserified < BROWSERIFY_RATELIMIT
    lastBrowserified = startTime

    watchReporter(path: file, type: 'changed') for file in files if files

    bundler.bundle(debug: config.source_maps)
      .on('error', errorReporter)
      .pipe(source(options.name))
      .pipe(gulp.dest(options.dest))
      .on('end', -> benchmarkReporter('Browserified', startTime))

  # bundler.on('file', (file)-> log("Browserifying #{pathNormalize(file)}", 'cyan'))
  bundler.on('update', compile) if options.watch
  compile()

processJavascripts = (options = {})->
  settings = _.extend {}, options,
    name: config.codename + '-app.js'
    dest: ASSETS_LOCATION

  compileJavascripts("#{APP_LOCATION}/javascripts/client/index.coffee", settings)

gulp.task 'watch', ->
  processJavascripts(watch: true)
  templates = [
    "#{APP_LOCATION}/templates/**/*.jade"
  ]
  gulp.watch(templates).on 'change', (event)->
    watchReporter(event)
    compileJavascripts(watch: true)
ghost commented 10 years ago

If jadeify emits 'file' events on the transform stream then this will work as you are proposing. Here's what brfs does: https://github.com/substack/brfs/blob/master/index.js#L90

max-degterev commented 10 years ago

cool, thanks. looks like I'm not the only one having this problem https://github.com/domenic/jadeify/issues/11