Giter VIP home page Giter VIP logo

watchify's Introduction

watchify

watch mode for browserify builds

build status

Update any source file and your browserify bundle will be recompiled on the spot.

example

$ watchify main.js -o static/bundle.js

Now as you update files, static/bundle.js will be automatically incrementally rebuilt on the fly.

The -o option can be a file or a shell command (not available on Windows) that receives piped input:

watchify main.js -o 'exorcist static/bundle.js.map > static/bundle.js' -d
watchify main.js -o 'uglifyjs -cm > static/bundle.min.js'

You can use -v to get more verbose output to show when a file was written and how long the bundling took (in seconds):

$ watchify browser.js -d -o static/bundle.js -v
610598 bytes written to static/bundle.js (0.23 seconds) at 8:31:25 PM
610606 bytes written to static/bundle.js (0.10 seconds) at 8:45:59 PM
610597 bytes written to static/bundle.js (0.14 seconds) at 8:46:02 PM
610606 bytes written to static/bundle.js (0.08 seconds) at 8:50:13 PM
610597 bytes written to static/bundle.js (0.08 seconds) at 8:58:16 PM
610597 bytes written to static/bundle.js (0.19 seconds) at 9:10:45 PM

usage

Use watchify with all the same options as browserify except that -o (or --outfile) is mandatory. Additionally, there are also:

Standard Options:

  --outfile=FILE, -o FILE

    This option is required. Write the browserify bundle to this file. If
    the file contains the operators `|` or `>`, it will be treated as a
    shell command, and the output will be piped to it.

  --verbose, -v                     [default: false]

    Show when a file was written and how long the bundling took (in
    seconds).

  --version

    Show the watchify and browserify versions with their module paths.
Advanced Options:

  --delay                           [default: 100]

    Amount of time in milliseconds to wait before emitting an "update"
    event after a change.

  --ignore-watch=GLOB, --iw GLOB    [default: false]

    Ignore monitoring files for changes that match the pattern. Omitting
    the pattern will default to "**/node_modules/**".

  --poll=INTERVAL                   [default: false]

    Use polling to monitor for changes. Omitting the interval will default
    to 100ms. This option is useful if you're watching an NFS volume.

methods

var watchify = require('watchify');

watchify(b, opts)

watchify is a browserify plugin, so it can be applied like any other plugin. However, when creating the browserify instance b, you MUST set the cache and packageCache properties:

var b = browserify({ cache: {}, packageCache: {} });
b.plugin(watchify);
var b = browserify({
  cache: {},
  packageCache: {},
  plugin: [watchify]
});

By default, watchify doesn't display any output, see events for more info.

b continues to behave like a browserify instance except that it caches file contents and emits an 'update' event when a file changes. You should call b.bundle() after the 'update' event fires to generate a new bundle. Calling b.bundle() extra times past the first time will be much faster due to caching.

Important: Watchify will not emit 'update' events until you've called b.bundle() once and completely drained the stream it returns.

var fs = require('fs');
var browserify = require('browserify');
var watchify = require('watchify');

var b = browserify({
  entries: ['path/to/entry.js'],
  cache: {},
  packageCache: {},
  plugin: [watchify]
});

b.on('update', bundle);
bundle();

function bundle() {
  b.bundle()
    .on('error', console.error)
    .pipe(fs.createWriteStream('output.js'))
  ;
}

options

You can to pass an additional options object as a second parameter of watchify. Its properties are:

opts.delay is the amount of time in milliseconds to wait before emitting an "update" event after a change. Defaults to 100.

opts.ignoreWatch ignores monitoring files for changes. If set to true, then **/node_modules/** will be ignored. For other possible values see Chokidar's documentation on "ignored".

opts.poll enables polling to monitor for changes. If set to true, then a polling interval of 100ms is used. If set to a number, then that amount of milliseconds will be the polling interval. For more info see Chokidar's documentation on "usePolling" and "interval". This option is useful if you're watching an NFS volume.

var b = browserify({ cache: {}, packageCache: {} });
// watchify defaults:
b.plugin(watchify, {
  delay: 100,
  ignoreWatch: ['**/node_modules/**'],
  poll: false
});

b.close()

Close all the open watch handles.

events

b.on('update', function (ids) {})

When the bundle changes, emit the array of bundle ids that changed.

b.on('bytes', function (bytes) {})

When a bundle is generated, this event fires with the number of bytes.

b.on('time', function (time) {})

When a bundle is generated, this event fires with the time it took to create the bundle in milliseconds.

b.on('log', function (msg) {})

This event fires after a bundle was created with messages of the form:

X bytes written (Y seconds)

with the number of bytes in the bundle X and the time in seconds Y.

working with browserify transforms

If your custom transform for browserify adds new files to the bundle in a non-standard way without requiring. You can inform Watchify about these files by emiting a 'file' event.

module.exports = function(file) {
  return through(
    function(buf, enc, next) {
      /*
        manipulating file content
      */
      
      this.emit("file", absolutePathToFileThatHasToBeWatched);
      
      next();
    }
  );
};

install

With npm do:

$ npm install -g watchify

to get the watchify command and:

$ npm install watchify

to get just the library.

troubleshooting

rebuilds on OS X never trigger

It may be related to a bug in fsevents (see #250 and stackoverflow). Try the --poll flag and/or renaming the project's directory - that might help.

watchify swallows errors

To ensure errors are reported you have to add a event listener to your bundle stream. For more information see (browserify/browserify#1487 (comment) and stackoverflow)

Example:

var b = browserify();
b.bundle()
  .on('error', console.error)
   ...
;

see also

  • budo – a simple development server built on watchify
  • errorify – a plugin to add error handling to watchify development
  • watchify-request – wraps a watchify instance to avoid stale bundles in HTTP requests
  • watchify-middleware – similar to watchify-request, but includes some higher-level features

license

MIT

watchify's People

Contributors

a0viedo avatar andrewrk avatar andreypopp avatar ansis avatar baileyparker avatar bermi avatar brianmhunt avatar burdiyan avatar davidnpma avatar es128 avatar feross avatar franleplant avatar glenjamin avatar goto-bus-stop avatar hughsk avatar hurrymaplelad avatar jakemhiller avatar jeffchan avatar jmm avatar jmorrell avatar juliangruber avatar mafintosh avatar mattdesl avatar mjomble avatar mreinstein avatar myshov avatar soryy708 avatar stevemao avatar tmpvar avatar zertosh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

watchify's Issues

watchify loses expose binding on update

Hi, I'm trying to use watchify with karma but watchify doesn't expose require after the update. After the first bundle() call everything is ok, require is exposed to the global scope, but after update - it's gone.

Here's one of watchify modified tests

var test = require('tape');
var watchify = require('../');
var browserify = require('browserify');
var vm = require('vm');

var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');

var os = require('os');
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());

mkdirp.sync(tmpdir);

var file = path.join(tmpdir, 'main2.js');
fs.writeFileSync(file, 'console.log(555); module.exports = function(){ console.log(123); };');


test('require api', function (t) {
    t.plan(5);
    var w = watchify(browserify(file, watchify.args));
        w.require(file, { expose: 'EXPOSE_TEST' });

    w.on('update', function () {
        w.bundle(function (err, src) {
            t.ifError(err);

            src+='require("EXPOSE_TEST")();';

            t.equal(run(src), '777\n888\n');
            w.close();
        });
    });
    w.bundle(function (err, src) {
        t.ifError(err);

        src+='require("EXPOSE_TEST")();';    

        t.equal(run(src), '555\n123\n');

        setTimeout(function () {
            fs.writeFile(file, 'console.log(777); module.exports = function(){ console.log(888); };', function (err) {
                t.ifError(err);
            });
        }, 1000);
    });
});

function run (src) {
    var output = '';
    function log (msg) { output += msg + '\n' }
    vm.runInNewContext(src, { console: { log: log } });
    return output;
}

With detect-globals, watching doesn't work

Whether using --detect-globals via the command line or via the local library, the code is bundled once and then the process exits. As far as I can tell, the 'update' event doesn't fire. This is using 0.7.2 with browserify 3.44.0.

This seems similar to #33, as the 'update' event never fires and I'm on a PC.

The full command that I'm using in git-bash, in case it matters:
watchify --detect-globals false --external async test/all-tests.js -o test/all-tests-built.js

If I take out --detect-globals false it watches as expected.

Include the queuedDeps in the update event

It would be great to know, upon an update event is emitted, what files have changed in the latest update.

This will make it nicer when rebuilds occur to, on the user-side, output this handy information to the log or console and track what has been changed.

Many thanks!

Suggesting verbose stream output option in API

The verbose command only seems to work on the command-line. (i.e., watchify checks argv in bin/cmd.js), but not in the API when doing a require('watchify'). This would be nice to have as an option to pass when using tools such as Gulp and vinyl-source-stream.

Please forgive me if this already exists somehow and I'm just not seeing it. I've noticed some tutorial examples passing {debug:true} or {verbose:true} to .bundler.bundle() before pipe()'ing, but I have had no luck with either.

Attempted with:
"gulp": "~3.6.2",
"watchify": "~0.8.2",
"vinyl-source-stream": "~0.1.1"

stops watching if a namespace is set

if I set the name of the object to access the bundle code with the --s options...

$ watchify main.js -d --s foo -o ../public/js/foo.js

...the script ends after having generated the new js.

if I omit that option...

$ watchify main.js -d -o ../public/js/foo.js

... watchify correctly keeps running, and recompiling the js when a module gets modified.

Fullpaths: undesired local system output

Sorry this might not quite be the appropriate place for this.

Just spent a couple of hours scratching my head trying to figure out why my output bundle was riddled with full system paths on my local machine until I discovered it was this option from watchify.args:

fullPaths: true

In the docs I see:

When creating the browserify instance b you MUST set these properties in the constructor:

var b = browserify({ cache: {}, packageCache: {}, fullPaths: true })

Removing fullPaths: true fixes my issue though I haven't tested if the code actually runs yet. Why is this option not optional? Is everyone using this plugin happily bundling their personal system paths in builds or is there a way around this?

Write to stdout?

It would be handy if watchify could write to stdout instead of requiring an output file.

Use case: When the browserify build fails due to a syntax error it would be nice to be able to overwrite the bundle files (and thereby making it extremely visible to the dev that something has gone wrong). Today watchify just leaves the old build in place, meaning you have to keep an eye on the console while developing.

Does this sound totally far fetched?

Thanks
Jonas

--standalone causes watchify to exit immediately

The --standalone option causes watchify to exit immediately after writing the bundle. The bundle itself works fine though.

watchify index.js --standalone Module -o module.js

Occurs at least on Windows (8.1, x64).
Node version v0.10.25,
Watchify version v0.6.3

Option to ignore modules in `node_modules`

Basically I have a project template where I use node-dev and browserify, the browserify is used twice — one instance generates code to execute on server and prerender UI, another — to generate code and serve to client.

When in dev mode it's a lot of watchers and it runs out of fds very quickly. I think watchify can have an option to ignore modules in node_modules cause 99.99% of developers don't need that functionality.

Continue even where bundle fails

When a bundle fails right now with something like (if you will pardon the coffeescript):

    w = watchify(BROWSERIFY_OPTS)
    w.on('update', -> 
      w.bundle(BUNDLE_OPTS)
        .on('error', (e) ->
          console.error("Error", e)
        )
        .on('end', ->
          console.log "Completed update ..."
        )
        .pipe(fs.createWriteStream(ALL_JS))
    )

then it seems that watchify stops watching.

What's the right way to have watchify continue watching for changes, in spite of the error?

Watchify Stops Listening to Dependency Changes After Failed Transform

When using watchify with for example the reactify transform, and the transform fails, watchify will only listen for changes to the main file, and not it's dependencies.

It looks like a regression of issue #3, and git bisect shows it as introduced in bcda5eb

index.js:

    require("./test.jsx");

test.jsx:

    module.export = "test";

Run with watchify:

    $ watchify  -d -v -t reactify index.js -o bundle.js

Watchify will now stop watching test.jsx if you add a syntax error in it (add "..." for example).

change event firing multiple times from a single save

Recently upgraded to the latest version of watchify from 0.4.1 and all of the sudden i'm getting multiple change events for every file save (editor - sublime text 3). It seems like using fs.watch directly instead of chokidar is probably the culprit here.

OSX: fs.watch bounce triggers build twice

At least on my system OS X 10.9, saving a file twiggers two change events:

watchify -v src/app.js -o app/app.bundle.js

touch src/app.js

Result:

1562124 bytes written to app/app.bundle.js
1562124 bytes written to app/app.bundle.js

#1 attempts to fix this by adding a debounce with a 2 second window, but on my system the window is a bit larger than that (~2500ms).

What about switching to a non-core file watching lib, such as chokidar (also used by chrisdickinson/beefy)? @substack?

Watchify execution fails when I install Browserify first

Hello,
I have a weird behaviour when I want to execute watchify.
If I install watchify first, and then browserify, I have no error.
The error happens only when I install browserify first. This is problematic because I have those two modules in my project depencendies, so when I type 'npm install', browserify is always installed before watchify.

Here is the complete error :

module.js:340                                          
    throw err;                                             
    ^                                                                      
Error: Cannot find module 'browserify'
    at Function.Module._resolveFilename (module.js:338:15)                                                                            
    at Function.Module._load (module.js:280:25)                                    
    at Module.require (module.js:364:17)                                                    
    at require (module.js:380:17)                
    at Object.<anonymous> (/home/vagrant/node_modules/js/angulpify-test/watchify/index.js:3:18)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)

Watchify stopped working with latest version

I updated watchify today and now I keep getting this.
Can't really figure out what's happening.

/Users/clemens/Projects/booze-boy-client/node_modules/watchify/index.js:47
            tr.on('file', function (file) {
               ^
TypeError: Cannot call method 'on' of undefined
    at Stream.<anonymous> (/Users/clemens/Projects/booze-boy-client/node_modules/watchify/index.js:47:16)
    at Stream.EventEmitter.emit (events.js:117:20)
    at Transform.EventEmitter.emit (events.js:98:17)
    at Deps.EventEmitter.emit (events.js:98:17)
    at /Users/clemens/Projects/booze-boy-client/node_modules/watchify/node_modules/browserify/node_modules/module-deps/index.js:213:22
    at nr (/Users/clemens/Projects/booze-boy-client/node_modules/watchify/node_modules/browserify/node_modules/module-deps/index.js:243:13)
    at /Users/clemens/Projects/booze-boy-client/node_modules/watchify/node_modules/browserify/node_modules/module-deps/index.js:227:21
    at /Users/clemens/Projects/booze-boy-client/node_modules/watchify/node_modules/browserify/node_modules/resolve/lib/async.js:35:29
    at /Users/clemens/Projects/booze-boy-client/node_modules/watchify/node_modules/browserify/node_modules/resolve/lib/async.js:93:39
    at /Users/clemens/Projects/booze-boy-client/node_modules/watchify/node_modules/browserify/node_modules/resolve/lib/async.js:59:30

npm ERR! [email protected] watch-tests: `watchify test/*.js -o public/tests.bundle.js -dv`

edit: just tried watchify 0.9.0. same problem.
browserify works just fine on the same code.

expose browserify

Consider this: I want to either use watchify or browserify depending on a command line option given. I can add a project dependency on browserify and watchify and then decide which one to use when the time comes. But it might make more sense to depend only on watchify and then use watchify.browserify if the -w switch in my app is not present.

Watchify is breaking .require() calls with the expose option

When the bundler is an instance of browserify, then this code works fine:

    var bundler = browserify({
            entries:        ['main.js],
            insertGlobals:  false,
            debug:          !settings.PRODUCTION // for source maps
        })

    bundler.require('/home/xxx/var/local/tmp/client_settings.json', {
        expose: 'client_settings.json'
    })

but when I wrap this with watchify like that:

    var bundler = watchify(browserify({
            entries:        ['main.js'],
            insertGlobals:  false,
            debug:          !settings.PRODUCTION // for source maps
        }), {
            watch: false
        })

    bundler.require('/home/xxx/var/local/tmp/client_settings.json', {
        expose: 'client_settings.json'
    })

then this error is thrown when bundling through a gulp task

TypeError: Cannot set property 'client_settings.json' of undefined
    at Browserify.<anonymous> (/home/xxx/node_modules/watchify/index.js:20:27)
    at Browserify.emit (events.js:95:17)
    at Transform._transform (/home/xxx/node_modules/browserify/index.js:475:14)
    at Transform._read (/home/xxx/node_modules/browserify/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10)
...

require= disappears after rebundle

I call browserify from gulpfile.js.
I'm making a build which should be usable by other builds, that's why I use bundle.require(...).

The problem is: require= is present in the first build, but after I update something and watchify rebuilds it, the new build does not have require= at the top. So client-side require stops to work.

My config (a bit simpified) is:

var opts = {
  debug:        true,
  cache:        {},
  packageCache: {},
  fullPaths:    true,
  dst:       './public/js/auth/authModal.js',
});

var bundler = browserify(opts);
bundler.require('auth/client/authModal');

bundler.rebundle = function() {
  this.bundle()
    .pipe(source(path.basename(this._options.dst)))
    .pipe(gulp.dest(path.dirname(this._options.dst)));
};
bundler.on('update', bundler.rebundle);
bundler = watchify(bundler);

Update event never fired

I have this "exotic" gulp setup but watchify does never fire the update event when I change main.js:

function bundleJs(watch, cb) {
    var bundler;

    // paths.browserEntry is an absolute path like
    // /home/michael.heuberger/binarykitchen/code/xxx/src/browser/main.js

    if (watch) {
        bundler = watchify(paths.browserEntry);
    } else {
        bundler = watchify.browserify(paths.browserEntry);
    }

    function rebundle(cb) {
        // clean first before rebundling
        fs.remove(paths.bundledScriptsDir, function(err) {
            if (err) {
                util.log(err);
                cb();
            } else {
                bundler
                    .transform('packageify')
                    .bundle({
                        insertGlobals:  false,
                        debug:          !settings.PRODUCTION // for source maps
                    })

                    .on('error', util.log)
                    .on('log',   util.log)
                    .on('end',   cb)

                    .pipe(source(paths.browserEntry)) // vinyl-source-stream
                    .pipe(buffer()) // because the next steps do not support streams
                    // just keep an unminified one for local development only
                    .pipe(concat('bundle.min.js'))
                    .pipe(uglify())
                    .pipe(gulp.dest(paths.bundledScriptsDir));
            }
        });
    }

    // when not watching, just bundle once
    if (!watch) {
        rebundle(cb);
    } else {
        bundler.on('update', rebundle);
        cb();
    }
}

gulp.task('browserify', function(cb) {
    bundleJs(false, cb);
});

gulp.task('watchify', ['browserify'], function(cb) {
    bundleJs(true, cb);
});

Most likely I am doing something stupid here but couldn't figure it out why (the other browserify task works fine).

Changes to files are no longer detected after specific syntax errors

I get this for example in this case

watchify index.js -o build/bundle.js

With index.js:

var util = require('./util');
console.log(util.test());

And util.js:

var extra = require('./extra');
module.exports.test = extra.test;

And extra.js:

module.exports.test = function () { return 5; }

Now when I change util.js to something like this:

var extra = require('./extra');--
module.exports.test = extra.test;

watchify correctly shows a syntax error (the --). However if I change util.js back to what it was, no update event is fired and no bundle is built. If I then continue by saving index.js again, an update event is fired and the bundle is rebuilt. Also, from that point on, changes in util.js are again recognized.

Weirdly, watchify correctly seems to handle syntax errors in extra.js and index.js. I'm not quite sure why that would be the case. I tried a simpler example with only a single or with two files, but could not get it to fail in those cases.

File no longer watched following an error

After any error, the file that caused the error is no longer watched. Looks like this is because fs.watch only picks up the first change to a file. watchify closes FSWatchers and re-watches when the build succeeds—allowing it to detect future file changes, but for some reason it skips that step in the event of an error. Why doesn't it close and recreate FSWatchers in the event of an error?

In my light experimentation, chokidar doesn't have this issue (nor does it suffer from the issue where a single file save triggers multiple 'change' events in some cases). Why did watchify switch from chokidar to fs.watch recently?

I believe the solution to this issue is to either a) close and recreate FSWatchers even on error or b) use chokidar.

Watchify cancels overlapping Grunt Watches

I'm finding that watches on files in the dependency chain of my Browserify/Watchify bundles are only firing once, and are cancelled after Watchify builds the bundle. For instance, I have a watch that runs JSHint against all my JS that changes within the project.

watch: {
    appJs: {
        files: ['src/**/*.js'],
        tasks: ['newer:jshint:appJs']
    }
 }

Some of the files in (src/*/.js) are also included in my Browserify bundle. After my Browserify/Watchify task bundles the files once, my Grunt JSHint watch stops firing. Files that are in this same glob, but aren't in the Watchify bundle (i.e. test spec files), continue to have the watch executed, as expected.

When commenting the following code from watchify/index.js, this problem is fixed (though I'm expecting there are negative side effects of this that I don't understand yet:

function invalidate (id) {
    delete cache[id];
    if (fwatchers[id]) {
        fwatchers[id].forEach(function (w) {
            // w.close(); <-- commenting this resolved the issue
        });
        delete fwatchers[id];
        delete fwatcherFiles[id];
    }

Watchify 0.7.0 is badly broken (doesn't cache)

Thanks so much for this awesome addition to browserify.

Unfortunately, as of 0.7.0, watchify no longer incrementally builds -- the cache is never loaded and big builds are slooooow. The problem was introduced in ad8e483, where the following line of code was dropped:

cache[dep.id] = dep;

Whoops.

As a proof of concept, I made this modification to index.js:

        // wait for the disk/editor to quiet down first:
        if (!pending) setTimeout(function () {
            pending = false;
            Object.keys(changingDeps).forEach(function(dep) {
              try {
                data = fs.readFileSync(dep);
              } catch(e) {
                b.emit.bind(b, 'error');
              }
            });
            b.emit('update', Object.keys(changingDeps));
            changingDeps = {};

        }, opts.delay || 600);

And caching once again works fine.

Clearly you'll want to be cleverer about not blocking on reading cache objects (or possibly you do want to block on cache object reads to avoid messiness with cache state inconsistency in rapid changes), but you need to reintroduce the business of actually caching code.

Probably a unit test for caching would serve well here...

V 1.0.1 errors on osx mavericks (regression?)

/Users/dmalam/Code/q/node_modules/watchify/index.js:100
delete cache[id];
^
TypeError: Cannot convert null to object
at invalidate (/Users/dmalam/Code/q/node_modules/watchify/index.js:100:22)
at EventEmitter. (/Users/dmalam/Code/q/node_modules/watchify/index.js:79:13)
at EventEmitter.emit (events.js:98:17)
at EventEmitter.FSWatcher.emit (/Users/dmalam/Code/q/node_modules/watchify/node_modules/chokidar/index.js:343:31)
at /Users/dmalam/Code/q/node_modules/watchify/node_modules/chokidar/index.js:264:18
at StatWatcher. (/Users/dmalam/Code/q/node_modules/watchify/node_modules/chokidar/index.js:241:9)
at StatWatcher.emit (events.js:98:17)
at StatWatcher._handle.onchange (fs.js:1109:10)

ENOENT on Windows with large standalone bundles

When watchify creates a new bundle after file updates, it will report an ENOENT error when it tries to rename the temporary .dotFile to outFile.

The cause for this just boggles my mind..

When the first bundle finishes on startup, watchify will do fs.rename(dotFile, outFile). For some weird reason this rename seems to be remembered and performed automatically on the following bundles.

When files are updated and a new bundle is generated, this bundle is renamed without watchify calling fs.rename - as a result, when watchify finally does call fs.rename, the file is already gone.

Watchify is still functional as the bundle is generated and the temporary file is renamed to the output file. The only visible problem is the extraneous error message.


This seems like a bug in Node.js itself, but I'm reporting it here for now since I'm too tired to come up with minimal repro steps for Node. The automatic rename happens without any calls to fs.rename (from watchify or any other module that the debugger could show). Process Monitor shows node.exe doing SetRenameInformationFile call for the dotFile to outFile. So it would seem like it's something in the native file system bindings that's causing this.

Node version v0.10.26

Transform fails when watchify is installed under node v0.10.28

With [email protected]

npm install [email protected]

We get this call stack with a liveify transform. Note that a browserify build works - it only fails under watchify. The same configuration works fine under [email protected].

/Users/stuart/src/ighs/node_modules/watchify/index.js:47
            tr.on('file', function (file) {
               ^
TypeError: Cannot call method 'on' of undefined
    at Stream.<anonymous> (/Users/stuart/src/ighs/node_modules/watchify/index.js:47:16)
    at Stream.EventEmitter.emit (events.js:117:20)
    at Transform.EventEmitter.emit (events.js:98:17)
    at Deps.EventEmitter.emit (events.js:98:17)
    at /Users/stuart/src/ighs/node_modules/browserify/node_modules/module-deps/index.js:213:22
    at nr (/Users/stuart/src/ighs/node_modules/browserify/node_modules/module-deps/index.js:243:13)
    at /Users/stuart/src/ighs/node_modules/browserify/node_modules/resolve/lib/async.js:42:21
    at /Users/stuart/src/ighs/node_modules/browserify/node_modules/resolve/lib/async.js:121:35
    at /Users/stuart/src/ighs/node_modules/browserify/node_modules/resolve/lib/async.js:93:39
    at /Users/stuart/src/ighs/node_modules/browserify/node_modules/resolve/lib/async.js:59:30

This is the relevant section from the gulpfile (LiveScript)

get-bundler = (instance) ->
  bundler = instance path.resolve paths.components, 'index.ls'
  bundler.transform liveify
  unless is-dev
    bundler.transform envify
    bundler.transform global: true, uglifyify
  bundler.require (path.resolve paths.components, 'index.ls'), expose: 'app'

build-config =
  debug: is-dev

update = (bundler) ->
  gulp-util.log 'Bundling'
  bundler.bundle build-config
  .on 'error' gulp-util.log
  .pipe vinyl-source-stream 'app.js'
  .pipe gulp.dest 'public'
  .on 'end' -> gulp-util.log 'Bundle complete'

gulp.task 'browserify' -> browserify |> get-bundler |> update

gulp.task 'watch' ->
  gulp.watch paths.ls, ['livescript']
  gulp.watch paths.watch-styles, ['styles']
  watch = watchify |> get-bundler
  watch.on 'update' -> update watch
  update watch

Watchify 'update' event not firing using Gulp task (on Windows)

I've got the following Gulp task, which had been working fine for a few days:

gulp.task('default', function() {
    var bundler = watchify('./public/js/main.js');

    bundler.transform('brfs');

    bundler.on('update', rebundle);

    function rebundle () {
        console.log('Bundling dev at:', new Date());

        return bundler.bundle({
            debug: true
        })
        .on('error', gutil.log)
        .pipe(source('app.js'))
        .pipe(gulp.dest('public/js/built'));
    }

    return rebundle();
});

I've noticed now, after installing and uninstalling some npm modules, and rebooting a few times, that this task no longer works... It doesn't appear that the update event is ever fired, either when editing/saving main.js or any of the traced dependencies underneath it.

I feel like I'm losing my mind here; can't imagine why this isn't working. The code is based off https://github.com/gulpjs/gulp/blob/master/docs/recipes/fast-browserify-builds-with-watchify.md and again, seemed to work fine for a few days.

watchify produces a much larger output file than directly invoking browserify

in my package.json:

"scripts": {
    "watchify": "watchify assets/javascripts/app.coffee -dv --extension .js --extension .coffee -o assets/javascripts/bundle.js",
    "browserify": "browserify assets/javascripts/app.coffee --extension .js --extension .coffee -o assets/javascripts/bundle.js"
  },
"browserify": {
    "transform": [
      "coffeeify",
      "brfs"
    ]
  }

My resulting bundle.js is 2-3X larger with watchify. I'm using [email protected] and [email protected] . What gives?

0.8.2 does not handle sub-files right

it no longer works if any required file changes more than once consecutively.
(only works the first time it changes)

I reverted to 0.8.1 and it was ok then.

.json files getting handled twice

Here's a simple test case:

var watchify = require('watchify')
var bundler = watchify('./data.json')

setInterval(function() {
  bundler.bundle().pipe(process.stdout)
}, 1000)
{"hello": "world"}

Running the script, the output of the bundle (minus the wrapper), looks like this the first time:

module.exports={"hello":"world"}

But every attempt after that comes out like so:

module.exports=module.exports={"hello":"world"}

That's fine most of the time for developing, but it's breaking one of our builds after inserting some node globals:

// whitespace added for legibility
module.exports=var process=require("__browserify_process"),
global=typeof self !== "undefined" ? self : typeof window !==
"undefined" ? window : {},Buffer=require("__browserify_Buffer"),
__filename="/../../node_modules/result-preview/manifest.json",
__dirname="/../../node_modules/result-preview";
module.exports={"hello":"world"}

Tried looking around to find out where it's coming from but no luck so far – any ideas? Otherwise I'll keep looking and see if I can submit a fix :)

External source maps and other options.

First off, thank you so much for watchify, it is a nice little tool!

Currently browserify creates a source map that is base64ed and appended to the bottom of the generated Javascript. By default it uses absolute paths for its sources as well.

I created an issue against the browserify project, and they responded with the following instructions browserify/browserify#603 (comment)

Would you be interested in a pull request that adds exorcist to watchify, along with some options to configure the output? If you are open to contributions, do you have anythings that you would like to see?

Bundle required in wrong order

Hi,

I was playing around with es6ify. When I use it with browserify everything works as expected, but when I use it with watchify then the bundles are required in the wrong order (yielding a dependency error).

I originally suspected the error in es6ify but maybe it's in watchify:

thlorenz/es6ify#34

I extracted my original code into this demo repository:

https://github.com/sebastiandeutsch/es6ify-test

I also added a seperate branch where you can see the difference between browserify and watchify:

sebastiandeutsch/es6ify-test@6ee4276

Any ideas where this behavior comes from?

Best

Sebastian

bundler.reload()?

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)

Watch transform targets

Hi. Currently (I believe) watchify does not watch files used with transform plugins.

I'm using jadeify with jade files and browserify isn't compiling the bundle.js when I save a .jade file.

triggering browserify builds on template file changes (brfs)

What is the best way to get watchify to trigger a new browserify build when a html template file changes using brfs?

app.js

var html = fs.readFileSync('foo.html');

package.json

  "scripts": {
    "watch-js": "watchify -t brfs app/app.js -o public/bundle.js -dv"
    ....
   }

foo.html

<h1>Boop</h1>

changed to

<h1>Beep</h1>

** would like to have watchify generate new bundle.js

Thx

npm install watchify fails with installTargetsError in 0.6.3

Here's my error log:

npm install watchify
npm http GET https://registry.npmjs.org/watchify
npm http 304 https://registry.npmjs.org/watchify
npm http GET https://registry.npmjs.org/shallow-copy/0.0.1
npm http GET https://registry.npmjs.org/through
npm http GET https://registry.npmjs.org/chokidar
npm http GET https://registry.npmjs.org/optimist
npm http 304 https://registry.npmjs.org/optimist
npm http 304 https://registry.npmjs.org/shallow-copy/0.0.1
npm http 304 https://registry.npmjs.org/chokidar
npm ERR! Error: No compatible version found: chokidar@'^0.8.1'
npm ERR! Valid install targets:
npm ERR! ["0.1.1","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.4.0","0.5.0","0.5.1","0.5.2","0.5.3","0.6.0","0.6.1","0.6.2","0.6
.3","0.7.0","0.7.1","0.8.0","0.8.1"]
npm ERR!     at installTargetsError (C:\Program Files\nodejs\node_modules\npm\lib\cache.js:685:10)
npm ERR!     at C:\Program Files\nodejs\node_modules\npm\lib\cache.js:607:10
npm ERR!     at saved (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-registry-client\lib\get.js:138:7)
npm ERR!     at Object.oncomplete (fs.js:107:15)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <[email protected]>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.