Permalink
Browse files

Added additional CORS header. Now using `chokidar` instead of `watchr…

…`. Fixes #6.
  • Loading branch information...
1 parent 6dca23a commit d0ed1006479f2fd91e56ef31c1dab7abfc768bed @shannonmoeller committed Nov 8, 2012
Showing with 53 additions and 26 deletions.
  1. +9 −3 README.md
  2. +4 −4 package.json
  3. +1 −1 src/cli.coffee
  4. +1 −0 src/connect-cors.coffee
  5. +38 −18 src/connect-reload.coffee
View
@@ -10,7 +10,7 @@ The stupid development server.
- CORS enabled.
Built with [Node.js][node] using [Connect][conn], [Socket.io][sock],
-[Commander.js][comm], and [watchr][wchr]. Inspired by visionmedia's [serve][serv]
+[Commander.js][comm], and [Chokidar][chok]. Inspired by visionmedia's [serve][serv]
and nodejitsu's [http-server][hser].
Installation
@@ -156,6 +156,11 @@ gradients.
Change Log
----------
+### 0.3.0
+- Now using `chokidar` instead of `watchr`. Vastly improves performance and
+ cross-platform reliability of file watching, especially when the server should
+ be idle. Fixes #6.
+
### 0.2.4
- Upgraded from `flow` to `step`.
@@ -168,7 +173,8 @@ Change Log
### 0.2.1
-- Now using `watchr` instead of `hound`. Common system and hidden files are now ignored. Fixes #5.
+- Now using `watchr` instead of `hound`. Common system and hidden files are now
+ ignored. Fixes #5.
- Now using `forever` instead of `supervisor` in `make test`.
License
@@ -197,6 +203,7 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+[chok]: https://github.com/paulmillr/chokidar/
[coas]: https://github.com/TrevorBurnham/connect-assets/
[coff]: http://coffeescript.org/
[comm]: http://visionmedia.github.com/commander.js/
@@ -210,4 +217,3 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[serv]: https://github.com/visionmedia/serve/
[sock]: http://socket.io/
[styl]: http://learnboost.github.com/stylus/
-[wchr]: https://github.com/bevry/watchr/
View
@@ -1,11 +1,11 @@
{
"name": "workit",
- "version": "0.2.4",
+ "version": "0.3.0",
"description": "The stupid development server. Serves CoffeeScript, Jade, and Stylus like a champ. Reloads browser on source-file change. CORS enabled.",
"keywords": ["assets", "compile", "cors", "live", "preprocess", "proxy", "reload", "serve", "static", "watch"],
"author": "Shannon Moeller <me@shannonmoeller.com> (http://shannonmoeller.com)",
"contributors": ["Patrik Votoček <patrik@votocek.cz> (http://patrik.votocek.cz)"],
- "main": "src/cli.coffee",
+ "main": "src/workit.coffee",
"bin": "./bin/workit",
"repository": {
"type": "git",
@@ -16,6 +16,7 @@
"watch": "make watch"
},
"dependencies": {
+ "chokidar": "*",
"coffee-script": "*",
"commander": "*",
"connect": "*",
@@ -24,8 +25,7 @@
"snockets": "*",
"socket.io": "*",
"step": "*",
- "stylus": "*",
- "watchr": "*"
+ "stylus": "*"
},
"devDependencies": {
"forever": "*"
View
@@ -3,7 +3,7 @@ commander = require 'commander'
path = require 'path'
# Arguments
-commander.version('0.2.4')
+commander.version('0.3.0')
.usage('[options] [dir]')
.option('-a, --address <string>', 'set hostname [localhost]')
.option('-f, --format <string>', 'connect logger format [dev]', 'dev')
@@ -7,6 +7,7 @@ url = require 'url'
module.exports = (req, res, next) ->
# Enable CORS for all requests
res.setHeader 'Access-Control-Allow-Origin', '*'
+ res.setHeader 'Access-Control-Allow-Headers', 'X-Requested-With'
# Guard proxy requests
return next() unless req.url.slice(0, 14) is '/connect-cors/'
@@ -1,11 +1,13 @@
# Modules
+chokidar = require 'chokidar'
path = require 'path'
socketio = require 'socket.io'
util = require 'util'
-watchr = require 'watchr'
# Prozac
-debounce = (fn, timeout) ->
+debounce = (fn) ->
+ timeout = null
+
return ->
clearTimeout timeout
timeout = setTimeout fn, 50
@@ -30,29 +32,47 @@ client = ->
target = document.getElementsByTagName('script')[0]
target.parentNode.insertBefore script, target.nextSibling
-# Export middleware
+# Export generator
module.exports = ({address, dir, port, server}) ->
+ connections = 0
+ timeout = null
+ watcher = null
+
# Prep client-side script
- client = util.format "(#{client}());", address, port
+ script = util.format "(#{client}());", address, port
- # Start watching files and open socket
+ # Open socket
io = socketio.listen server, 'log level': 0
- # Reasonable emitter
- emit = debounce ->
+ # Reload handler
+ reload = debounce ->
io.sockets.emit 'connect-reload'
- # Reload emitter
- reload = (file) ->
- # Ignore hidden files
- emit() if path.basename(file).indexOf '.'
+ # Watch files
+ watch = ->
+ watcher = chokidar
+ .watch(dir, ignored: /\/\.|node_modules/, persistent: true)
+ .on('change', reload)
+ .on('unlink', reload)
+
+ # Unwatch files
+ unwatch = ->
+ watcher?.close()
+ watcher = null
+
+ # Manage connections
+ io.sockets.on 'connection', (s) ->
+ # Start watching
+ connections += 1
+ timeout = clearTimeout timeout
+
+ # Create watcher if needed
+ watch() unless watcher
- # Bind emitter to file changes
- watchr.watch
- ignoreHiddenFiles: true
- ignorePatterns: true
- listener: reload
- path: dir
+ s.on 'disconnect', ->
+ # Stop watching
+ connections -= 1
+ timeout = setTimeout unwatch, 100 unless connections
# Return middleware
({url}, res, next) ->
@@ -61,4 +81,4 @@ module.exports = ({address, dir, port, server}) ->
# RAM for the win
res.setHeader 'Content-Type', 'text/javascript'
- res.end client
+ res.end script

0 comments on commit d0ed100

Please sign in to comment.