1 | var watchDir = require('./watch');
|
2 | var tinylr = require('tiny-lr');
|
3 | var growl = require('growl');
|
4 | var path = require('path');
|
5 | var Stream = require('stream');
|
6 | var PassThrough = require('stream').PassThrough;
|
7 | var env = process.env.NODE_ENV || 'development';
|
8 |
|
9 | function getSnippet (port) {
|
10 |
|
11 | var snippet = [
|
12 | "<!-- livereload snippet -->",
|
13 | "<script>document.write('<script src=\"http://'",
|
14 | " + (location.host || 'localhost').split(':')[0]",
|
15 | " + ':" + port + "/livereload.js?snipver=1\"><\\/script>')",
|
16 | "</script>",
|
17 | ""
|
18 | ].join('\n');
|
19 | return snippet;
|
20 | }
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | module.exports = function (root, opts) {
|
29 | if (env !== 'development') {
|
30 | return async (ctx, next) => {
|
31 | await next();
|
32 | }
|
33 | }
|
34 | opts = opts || {};
|
35 | var port = opts.port || 35729;
|
36 | opts.includes = (opts.includes || []).concat(['js', 'css', 'html']);
|
37 | opts.excludes = (opts.excludes || []).concat(['node_modules']);
|
38 | var snippet = getSnippet(port);
|
39 |
|
40 | var server = new tinylr();
|
41 | server.listen(port, err => {
|
42 | if (err) { throw err; }
|
43 | })
|
44 | watchDir(root, opts, function (file) {
|
45 |
|
46 | var basename = path.basename(file);
|
47 | growl('Change file: ' + basename + '. Reloading...', { image: 'Safari', title: 'liveload' });
|
48 | server.changed({
|
49 | body: { files: file }
|
50 | })
|
51 | })
|
52 | return async function liveload(ctx, next) {
|
53 | await next();
|
54 | if (ctx.response.type && ctx.response.type.indexOf('html') < 0) return;
|
55 |
|
56 | var body = ctx.body;
|
57 | var len = ctx.response.length;
|
58 |
|
59 | if (Buffer.isBuffer(ctx.body)) {
|
60 | body = ctx.body.toString();
|
61 | }
|
62 |
|
63 | if (typeof body === 'string') {
|
64 | ctx.body = body.replace(/<\/body>/, w => {
|
65 | if (len) { ctx.set('Content-Length', len + Buffer.byteLength(snippet)); }
|
66 | return snippet + w;
|
67 | });
|
68 | } else if (body instanceof Stream) {
|
69 | var stream = ctx.body = new PassThrough();
|
70 | body.setEncoding('utf8');
|
71 | if (len) { ctx.set('Content-Length', len + Buffer.byteLength(snippet)); }
|
72 | body.on('data', function (chunk) {
|
73 | chunk = chunk.replace(/<\/body>/, w => {
|
74 | return snippet + w;
|
75 | });
|
76 | stream.write(chunk);
|
77 | });
|
78 | body.on('end', () => {
|
79 | stream.end();
|
80 | })
|
81 | body.on('error', ctx.onerror);
|
82 | }
|
83 | }
|
84 | } |
\ | No newline at end of file |