1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | var util = require('util'),
|
7 | path = require('path'),
|
8 | assert = require('assert'),
|
9 | spawn = require('child_process').spawn,
|
10 | merge = require('deepmerge'),
|
11 | tinylr = require('tiny-lr'),
|
12 | es = require('event-stream'),
|
13 | Q = require('q'),
|
14 | chalk = require('chalk'),
|
15 | debug = require('debug')('gulp-live-server');
|
16 |
|
17 | var config = {},
|
18 | server = undefined,
|
19 | lr = undefined,
|
20 | info = chalk.gray,
|
21 | error = chalk.bold.red;
|
22 |
|
23 | var callback = {
|
24 | processExit: function (code, sig) {
|
25 | debug(info('Main process exited with [code => %s | sig => %s]'), code, sig);
|
26 | server && server.kill();
|
27 | },
|
28 |
|
29 | serverExit: function (code, sig) {
|
30 | debug(info('server process exited with [code => %s | sig => %s]'), code, sig);
|
31 | if(sig !== 'SIGKILL'){
|
32 |
|
33 | process.exit(0);
|
34 | }
|
35 | },
|
36 |
|
37 | lrServerReady: function () {
|
38 | console.log(info('livereload[tiny-lr] listening on %s ...'), config.livereload.port);
|
39 | },
|
40 |
|
41 | serverLog: function (data) {
|
42 | console.log(info(data.trim()));
|
43 | },
|
44 |
|
45 | serverError: function (data) {
|
46 | console.log(error(data.trim()));
|
47 | }
|
48 | };
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | module.exports = exports = (function() {
|
55 | var defaults = {
|
56 | options: {
|
57 | cwd: undefined
|
58 | },
|
59 | livereload: {
|
60 | port: 35729
|
61 | }
|
62 | };
|
63 | defaults.options.env = process.env;
|
64 | defaults.options.env.NODE_ENV = 'development';
|
65 |
|
66 | return function(args, options, livereload){
|
67 | config.args = util.isArray(args) ? args : [args];
|
68 |
|
69 | config.options = merge(defaults.options, options || {});
|
70 |
|
71 | if (livereload) {
|
72 | config.livereload = (typeof livereload === 'object' ? livereload : {port: livereload});
|
73 | }else{
|
74 | config.livereload = (livereload === false ? false : defaults.livereload);
|
75 | }
|
76 | return exports;
|
77 | };
|
78 | })();
|
79 |
|
80 |
|
81 |
|
82 |
|
83 | exports.script = path.join(__dirname, 'scripts/static.js');
|
84 |
|
85 |
|
86 |
|
87 |
|
88 | exports.new = function (script) {
|
89 | if(!script){
|
90 | return console.log(error('script file not specified.'));
|
91 | }
|
92 | var args = util.isArray(script) ? script : [script];
|
93 | return this(args);
|
94 | };
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | exports.static = function (folder, port) {
|
100 | var script = this.script;
|
101 | folder = folder || process.cwd();
|
102 | util.isArray(folder) && (folder = folder.join(','));
|
103 | port = port || 3000;
|
104 | return this([script, folder, port]);
|
105 | };
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | exports.start = function () {
|
111 | if (server) {
|
112 | debug(info('kill server'));
|
113 | server.kill('SIGKILL');
|
114 |
|
115 | server = undefined;
|
116 | } else {
|
117 | if(config.livereload){
|
118 | lr = tinylr(config.livereload);
|
119 | lr.listen(config.livereload.port, callback.lrServerReady);
|
120 | }
|
121 | }
|
122 |
|
123 | var deferred = Q.defer();
|
124 | server = spawn('node', config.args, config.options);
|
125 | server.stdout.setEncoding('utf8');
|
126 | server.stderr.setEncoding('utf8');
|
127 |
|
128 | server.stdout.on('data', function (data) {
|
129 | deferred.notify(data);
|
130 | callback.serverLog(data);
|
131 | });
|
132 | server.stderr.on('data', function (data) {
|
133 | deferred.notify(data);
|
134 | callback.serverError(data);
|
135 | });
|
136 | server.once('exit', function (code, sig) {
|
137 | deferred.resolve({
|
138 | code: code,
|
139 | signal: sig
|
140 | });
|
141 | callback.serverExit(code, sig);
|
142 | });
|
143 |
|
144 | process.listeners('exit') || process.once('exit', callback.processExit);
|
145 |
|
146 | return deferred.promise;
|
147 | };
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | exports.stop = function () {
|
153 | var deferred = Q.defer();
|
154 | if (server) {
|
155 | server.once('exit', function (code) {
|
156 | deferred.resolve(code);
|
157 | });
|
158 |
|
159 | debug(info('kill server'));
|
160 |
|
161 | server.kill('SIGKILL');
|
162 |
|
163 | server = undefined;
|
164 | }else{
|
165 | deferred.resolve(0);
|
166 | }
|
167 | if(lr){
|
168 | debug(info('close livereload server'));
|
169 | lr.close();
|
170 |
|
171 | lr = undefined;
|
172 | }
|
173 |
|
174 | return deferred.promise;
|
175 | };
|
176 |
|
177 |
|
178 |
|
179 |
|
180 | exports.notify = function (event) {
|
181 | if(event && event.path){
|
182 | var filepath = path.relative(__dirname, event.path);
|
183 | debug(info('file(s) changed: %s'), event.path);
|
184 | lr.changed({body: {files: [filepath]}});
|
185 | }
|
186 |
|
187 | return es.map(function(file, done) {
|
188 | var filepath = path.relative(__dirname, file.path);
|
189 | debug(info('file(s) changed: %s'), filepath);
|
190 | lr.changed({body: {files: [filepath]}});
|
191 | done(null, file);
|
192 | });
|
193 | };
|