审查视图

public/assets/libs/jcrop/node_modules/tiny-lr/readme.md 9.4 KB
景龙 authored
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
tiny-lr
-------

This script manages a tiny [LiveReload](http://livereload.com/) server
implementation you can spawn in the background.

It exposes:

- a background-friendly bin wrapper (thanks to
  [@FGRibreau](https://github.com/FGRibreau) [pid.js
  gist](https://gist.github.com/1846952))

- [Grunt tasks](https://github.com/mklabs/tiny-lr#using-grunt) to start the server and trigger reload notification. Every task
  name is prefixed by `tinylr-`.

- [Generic targets](https://github.com/mklabs/tiny-lr#using-make) to include in
  your Makefile (`include node_modules/tiny-lr/tasks/tiny-lr.mk`)

It doesn't have any watch ability, it must be done at the build process or
application level.

Instead, it exposes a very simple API to notify the server that some
changes have been made, that is then broadcasted to every livereload client
connected.

    # notify a single change
    curl http://localhost:35729/changed?files=style.css

    # notify using a longer path
    curl http://localhost:35729/changed?files=js/app.js

    # notify multiple changes, comma or space delimited
    curl http://localhost:35729/changed?files=index.html,style.css,docs/docco.css

Or you can bulk the information into a POST request, with body as a JSON array of files.

    curl -X POST http://localhost:35729/changed -d '{ "files": ["style.css", "app.js"] }'

As for the livereload client, you need to install the browser extension:
http://feedback.livereload.com/knowledgebase/articles/86242-how-do-i-install-and-use-the-browser-extensions-
(**note**: you need to listen on port 35729 to be able to use with your
brower extension)

or add the livereload script tag manually:
http://feedback.livereload.com/knowledgebase/articles/86180-how-do-i-add-the-script-tag-manually-
(and here you can choose whatever port you want)

## Integration

This package exposes a `bin` you can decide to install globally, but it's not recommended.

    tiny-lr --help

    Usage: tiny-lr [options]

    Options:
      -h, --help        - Show help usage
      -v, --version     - Show package version
      -p, --port        - Port to listen on (default: 35729)
      --pid             - Path to the generated PID file (default: ./tiny-lr.pid)


The best way to integrate the runner in your workflow is to add it as a `reload`
step within your build tool. This build tool can then use the internal binary
linked by npm in `node_modules/.bin/tiny-lr` to not rely on global installs (or
use the server programmtically).

You can start the server using the binary provided, or use your own start script.

```js
var tinylr = require('tiny-lr');

// standard LiveReload port
var port = 35729;

// tinylr(opts) => new tinylr.Server(opts);
tinylr().listen(port, function() {
  if(err) {
    // deal with err
    return;
  }

  console.log('... Listening on %s (pid: %s) ...', port);
})
```

You can define your own route and listen for specific request:

```js
var server = tinylr();

server.on('GET /myplace', function(req, res) {
  res.write('Mine');
  res.end();
})
```

And stop the server manually:

```js
server.close();
```

This will close any websocket connection established and emit a close event.

### Middleware

To use as a connect / express middleware, tiny-lr needs query /
bodyParse middlewares prior in the stack.

Any handled requests ends at the tinylr level, not found and errors are
nexted to the rest of the stack.

```js
// This binds both express app and tinylr on the same port
var app = express();
app.use(express.query())
  .use(express.bodyParser())
  .use(tinylr.middleware({ app: app }))
  .use(express.static(path.resolve('./')))
  .use(express.directory(path.resolve('./')))
  .listen(35729, function() {
    console.log('Listening on %d', 35729);
  })
```

The port you listen on is important, and tinylr should **always** listen on
the LiveReload standard one: `35729`. Otherwise, you won't be able to rely
on the browser extensions, though you can still use the manual snippet
approach.

You can also start two different servers, one on your app port, the
other listening on the LiveReload port. Check the
`examples/express/server.js` file to see how.

### Using grunt

This package exposes a `tasks/` directory, that you can use within your Gruntfile with:

```js
grunt.loadNpmTasks('tiny-lr');
```

- tinylr-start    - Starts a new tiny-lr Server, with the provided port.
- tinylr-reload   - Sends a reload notification to the previously started server.

`tinylr-start` should be used with the `watch` task, probably with an alias
that triggers both `tinylr-start watch` tasks.

`tinylr-reload` should be configured as a "watch" task in your Gruntfile.

```js
grunt.initConfig({
  watch: {
    reload: {
      files: ['**/*.html', '**/*.js', '**/*.css', '**/*.{png,jpg}'],
      tasks: 'tinylr-reload'
    }
  }
});

grunt.registerTask('reload', 'tinylr-start watch');
```


### Using make

See `tasks/tiny-lr.mk`.

Include this file into your project Makefile to bring in the following targets:

- start 						- Start the LiveReload server
- stop 							- Stops the LiveReload server
- livereload 				- alias to start
- livereload-stop 	- aias to stop

Then define your "empty" targets, and the list of files you want to monitor.

```make
CSS_DIR = app/styles
CSS_FILES = $(shell find $(CSS_DIR) -name '*.css')

# include the livereload targets
include node_modules/tiny-lr/tasks/*.mk

$(CSS_DIR): $(CSS_FILES)
  @echo CSS files changed: $?
    @touch $@
  curl -X POST http://localhost:35729/changed -d '{ "files": "$?" }'

reload-css: livereload $(CSS_DIR)

.PHONY: reload-css
```

The pattern is always the same:

- define a target for your root directory that triggers a POST request
- `touch` the directory to update its mtime
- add reload target with `livereload` and the list of files to "watch" as
  prerequisites

You can chain multiple "reload" targets in a single one:

```make
reload: reload-js reload-css reload-img reload-EVERYTHING
```

Combine this with [visionmedia/watch](https://github.com/visionmedia/watch) and
you have a livereload environment.

    watch make reload

    # add a -q flag to the watch command to suppress most of the annoying output
    watch -q reload

The `-q` flag only outputs STDERR, you can in your Makefile redirect the
output of your commands to `>&2` to see them in `watch -q` mode.


## Tests

    npm test

---


# TOC
   - [tiny-lr](#tiny-lr)
     - [GET /](#tiny-lr-get-)
     - [GET /changed](#tiny-lr-get-changed)
     - [POST /changed](#tiny-lr-post-changed)
     - [GET /livereload.js](#tiny-lr-get-livereloadjs)
     - [GET /kill](#tiny-lr-get-kill)
<a name="" />

<a name="tiny-lr" />
# tiny-lr
accepts ws clients.

```js
var url = parse(this.request.url);
var server = this.app;

var ws = this.ws = new WebSocket('ws://' + url.host + '/livereload');

ws.onopen = function(event) {
  var hello = {
    command: 'hello',
    protocols: ['http://livereload.com/protocols/official-7']
  };

  ws.send(JSON.stringify(hello));
};

ws.onmessage = function(event) {
  assert.deepEqual(event.data, JSON.stringify({
    command: 'hello',
    protocols: ['http://livereload.com/protocols/official-7'],
    serverName: 'tiny-lr'
  }));

  assert.ok(Object.keys(server.clients).length);
  done();
};
```

properly cleans up established connection on exit.

```js
var ws = this.ws;

ws.onclose = done.bind(null, null);

request(this.server)
  .get('/kill')
  .expect(200, function() {
    console.log('server shutdown');
  });
```

<a name="tiny-lr" />
# tiny-lr
<a name="tiny-lr-get-" />
## GET /
respond with nothing, but respond.

```js
request(this.server)
  .get('/')
  .expect('Content-Type', /json/)
  .expect('{"tinylr":"Welcome","version":"0.0.1"}')
  .expect(200, done);
```

unknown route respond with proper 404 and error message.

```js
request(this.server)
  .get('/whatev')
  .expect('Content-Type', /json/)
  .expect('{"error":"not_found","reason":"no such route"}')
  .expect(404, done);
```

<a name="tiny-lr-get-changed" />
## GET /changed
with no clients, no files.

```js
request(this.server)
  .get('/changed')
  .expect('Content-Type', /json/)
  .expect(/"clients":\[\]/)
  .expect(/"files":\[\]/)
  .expect(200, done);
```

with no clients, some files.

```js
request(this.server)
  .get('/changed?files=gonna.css,test.css,it.css')
  .expect('Content-Type', /json/)
  .expect('{"clients":[],"files":["gonna.css","test.css","it.css"]}')
  .expect(200, done);
```

<a name="tiny-lr-post-changed" />
## POST /changed
with no clients, no files.

```js
request(this.server)
  .post('/changed')
  .expect('Content-Type', /json/)
  .expect(/"clients":\[\]/)
  .expect(/"files":\[\]/)
  .expect(200, done);
```

with no clients, some files.

```js
var data = { clients: [], files: ['cat.css', 'sed.css', 'ack.js'] };

request(this.server)
  .post('/changed')
  .send({ files: data.files })
  .expect('Content-Type', /json/)
  .expect(JSON.stringify(data))
  .expect(200, done);
```

<a name="tiny-lr-get-livereloadjs" />
## GET /livereload.js
respond with livereload script.

```js
request(this.server)
  .get('/livereload.js')
  .expect(/LiveReload/)
  .expect(200, done);
```

<a name="tiny-lr-get-kill" />
## GET /kill
shutdown the server.

```js
var server = this.server;
request(server)
  .get('/kill')
  .expect(200, function(err) {
    if(err) return done(err);
    assert.ok(!server._handle);
    done();
  });
```

---

- 2013-01-21 - v0.0.4 - middleware support
- 2013-01-20 - v0.0.3 - serve livereload from repo (#4)
- 2013-01-12 - v0.0.2 - tasks - support for grunt 0.3.x (#1)
- 2013-01-05 - v0.0.1 - Initial release