UNPKG

4.22 kBJavaScriptView Raw
1const path = require('path');
2const url = require('url');
3
4let open;
5let connect;
6let connectLr;
7let tinyLr;
8let proxy;
9let serveStatic;
10
11function fixedBrowsers(value) {
12 if (typeof value === 'string') {
13 return value.replace(/\+/g, ' ').split(',').map(name => {
14 return name === 'chrome' ? 'google chrome' : name;
15 });
16 }
17}
18
19function run(done) {
20 tinyLr = tinyLr || require('tiny-lr');
21 connect = connect || require('connect');
22 connectLr = connectLr || require('connect-livereload');
23 serveStatic = serveStatic || require('serve-static');
24 proxy = proxy || require('proxy-middleware');
25
26 const app = connect();
27
28 const cwd = this.opts.cwd;
29 const exists = this.util.exists;
30 const options = this.opts;
31 const logger = this.logger;
32
33 const lrOptions = this.opts.pluginOptions['tiny-lr']
34 || this.opts.pluginOptions['live-reload']
35 || this.opts.pluginOptions.lr || {};
36
37 const port = options.flags.port || process.env.PORT || 3000;
38 const _port = process.env.LR_PORT || 35729;
39
40 let _proxy;
41
42 // early as possible
43 app.use(connectLr({
44 src: `//localhost:${_port}/livereload.js?snipver=1`,
45 port: _port,
46 }));
47
48 const serveDirs = lrOptions.serve || options.serve || [];
49 const sources = [path.relative(cwd, options.public) || '.'].concat(serveDirs);
50
51 logger.info('\r\r{% log Serving files from: %} %s\n',
52 sources.map(x => `{% yellow ${x} %}`).join('{% gray , %} '));
53
54 if (typeof options.flags.proxy === 'string') {
55 _proxy = options.flags.proxy;
56 _proxy.split(';').forEach(chunk => {
57 const _part = chunk.trim();
58
59 let _parts;
60
61 if (_part.indexOf('->') !== -1 || _part.indexOf(' ') !== -1) {
62 _parts = _part.split(/\*->\s*|\s+/);
63
64 let dest = _parts[2];
65
66 if (/^\d+/.test(dest)) {
67 dest = `:${dest}`;
68 }
69
70 if (dest.charAt() === ':') {
71 dest = `localhost${dest}`;
72 }
73
74 if (dest.indexOf('://') === -1) {
75 dest = `http://${dest}`;
76 }
77
78 _parts[0].split(',').forEach(sub => {
79 app.use(sub, proxy(`${dest}${dest.substr(-1) !== '/' ? sub : ''}`));
80 });
81 } else {
82 _parts = _part.match(/^(\w+:\/\/[\w:.]+)(\/.+?)?$/);
83
84 app.use(_parts[2] || '/', proxy(_part));
85 }
86 });
87 }
88
89 app.use((req, res, next) => {
90 if (req.method === 'GET') {
91 const name = url.parse(req.url).pathname;
92
93 // TODO: improve this behavior
94 if (path.basename(name).indexOf('.') > -1) {
95 return next();
96 }
97
98 const src = url.parse(req.url).pathname;
99 const file = path.join(options.public, src);
100
101 if (!exists(file)) {
102 const dir = path.dirname(file);
103 const prefix = exists(dir) ? `${path.dirname(src)}/` : '/';
104
105 req.url = `${prefix}${options.index || 'index.html'}`;
106 }
107 }
108
109 next();
110 });
111
112 app.use(serveStatic(options.public));
113
114 if (serveDirs) {
115 (!Array.isArray(serveDirs) ? [serveDirs] : serveDirs)
116 .forEach(dir => {
117 app.use(serveStatic(dir));
118 });
119 }
120
121 let LR;
122
123 app.listen(port, err => {
124 if (err) {
125 return done(err);
126 }
127
128 // restart
129 LR = tinyLr();
130 LR.listen(_port, () => {
131 logger.info('\r\r{% link http://localhost:%s %}%s\n',
132 port, _proxy ? ` {% gray (${_proxy.replace(/^https?:\/\//, '')}) %}` : '');
133
134 if (options.flags.open) {
135 open = open || require('open');
136 open(`http://localhost:${port}`, { app: fixedBrowsers(options.flags.open) || [] })
137 .catch(() => {
138 // do nothing
139 });
140 }
141
142 done();
143 });
144 });
145
146 this.on('end', (err, result) => {
147 if (!err) {
148 setTimeout(() => {
149 if (!result.output.length) {
150 Object.keys(LR.clients).forEach(k => {
151 LR.clients[k].send({
152 command: 'reload',
153 path: '',
154 });
155 });
156 } else {
157 LR.changed({
158 body: {
159 files: result.output,
160 },
161 });
162 }
163 }, lrOptions.timeout || 100);
164 }
165 });
166}
167
168module.exports = function $tinyLr(cb) {
169 if (this.opts.watch && (this.opts.flags.port || this.opts.flags.proxy)) {
170 run.call(this, cb);
171 } else {
172 cb();
173 }
174};