2012-08-24: JSReload now also supports Chrome/Mac.
This blog post explains how to use Node.js to reload a tab in Safari whenever a file changes. Alas, this solution only works on a Mac, because it relies on AppleScript to remotely control Safari. You can download it as project JSReload on GitHub.
I’m currently evaluating whether to switch from TextMate to Sublime Text. The only feature I miss on Sublime is a live preview of HTML files (or files that can be converted to HTML via a script – think Markdown).
We’ll look at two solutions:
- A shell script (powered by Node.js) that watches a directory. It reloads Safari whenever one of the .html or .css files in the directory changes.
In some ways that’s better than TextMate, because you can edit a CSS file and the corresponding HTML file is reloaded in Safari.
- A Grunt script that serves a different purpose: It watches a directory with AsciiDoc (.asc) files. When a file changes, that file is compiled to HTML and then Safari is reloaded.
The shell script watchdir.js
We use the Node.js function fs.watch()
to be notified if a file changes:
fs.watch(filename, [options], [listener])
The listener is called whenever the file changes whose name is filename
has a few quirks on Mac OS X, but it mostly works. Then we still need to reload Safari. And AppleScript lets us do that:
var code = '\
tell application "Safari"\n\
set mytab to first tab of first window\n\
We execute the AppleScript program in the variable code
via the shell command osascript
spawn("osascript", ["-e", code])
Node.js makes sure that everything is properly quoted and escaped.
files: [ '**/*.asc' ]
tasks: 'asciidoc reloadsafari'
We watch all AsciiDoc files (as specified via asciidoc.files
). If one of them changes, we first convert it to HTML via the asciidoc
shell command and then reload Safari. Both asciidoc
are custom Grunt tasks (included in the GitHub project). Hence, it should be easy to adapt this solution to different needs (e.g. Markdown).
Safari is perfect for previewing files for me, because I don’t use it for anything else.
But other browsers can probably be remote-controlled via Node.js, too. For example, via the following mechanisms:
If you don’t want to use scripts or the command line then you can use the Firefox add-on “Auto Reload
” by Yurii Zolot'ko. Alas, Chrome doesn’t have anything similar, only extensions that reload periodically, which I don’t consider good enough.
Lastly, there is the impressive Live.js
, but for that you need to insert a script tag into your HTML file. And you have to access your HTML via a server.
Conclusion: an app wish
The presented solution works quite well. But Sublime Text should really provide its own preview functionality. There seems to be an aversion to putting too much functionality into Sublime. Then how about a separate application? It would show a single browser window and watch a directory. You would be able to configure what files are watched and how they are converted to HTML. It should be possible to optionally make that conversion without creating files, by writing to stdout.
- HTML: Watch all .html and .css files. If one of them changes, reload the browser window.
- AsciiDoc: Watch all .asc files. If one of them changes, convert it to an HTML file and reload the browser window.
- Markdown: Watch all .md, .mdown and .markdown files. If one of them changes, translate it to HTML and pipe the result to the browser window.
If you find this idea appealing then you can vote for it
on UserEcho (the official way of giving feedback for Sublime Text).