UNPKG

2.53 kBJavaScriptView Raw
1#!/usr/bin/env node
2var connect = require('connect'),
3 colors = require('colors'),
4 WebSocket = require('faye-websocket'),
5 path = require('path'),
6 url = require('url'),
7 http = require('http'),
8 send = require('send'),
9 open = require('open'),
10 watchr = require('watchr'),
11 ws;
12
13var INJECTED_CODE = require('fs').readFileSync(__dirname + "/injected.html", "utf8");
14
15function escape(html){
16 return String(html)
17 .replace(/&(?!\w+;)/g, '&')
18 .replace(/</g, '&lt;')
19 .replace(/>/g, '&gt;')
20 .replace(/"/g, '&quot;');
21};
22
23// Based on connect.static(), but streamlined and with added code injecter
24function static(root) {
25 return function static(req, res, next) {
26 if ('GET' != req.method && 'HEAD' != req.method) return next();
27 var reqpath = url.parse(req.url).pathname;
28
29 function directory() {
30 var pathname = url.parse(req.originalUrl).pathname;
31 res.statusCode = 301;
32 res.setHeader('Location', pathname + '/');
33 res.end('Redirecting to ' + escape(pathname) + '/');
34 }
35
36 function error(err) {
37 if (404 == err.status) return next();
38 next(err);
39 }
40
41 function inject(stream) {
42 var x = path.extname(reqpath);
43 if (x == "" || x == ".html" || x == ".htm" || x == ".xhtml" || x == ".php") {
44 // We need to modify the length given to browser
45 var len = INJECTED_CODE.length + res.getHeader('Content-Length');
46 res.setHeader('Content-Length', len);
47 // Write the injected code
48 res.write(INJECTED_CODE);
49 }
50 }
51
52 send(req, reqpath)
53 .root(root)
54 .on('error', error)
55 .on('stream', inject)
56 .on('directory', directory)
57 .pipe(res);
58 };
59};
60
61function start(port, directory) {
62 port = port || 8080;
63 directory = directory || process.cwd();
64 // Setup a web server
65 var app = connect()
66 .use(static(directory)) // Custom static server
67 .use(connect.logger('dev'));
68 var server = http.createServer(app).listen(port);
69 // WebSocket
70 server.addListener('upgrade', function(request, socket, head) {
71 ws = new WebSocket(request, socket, head);
72 ws.onopen = function() { ws.send('connected'); }
73 });
74 // Setup file watcher
75 watchr.watch({
76 path: directory,
77 ignorePatterns: true,
78 ignoreHiddenFiles: true,
79 listener: function(eventName, filePath, fileCurrentStat, filePreviousStat) {
80 if (!ws) return;
81 if (path.extname(filePath) == ".css") ws.send('refreshcss');
82 else ws.send('reload');
83 }
84 });
85 // Output
86 console.log(('Serving "' + directory + '" at http://localhost:' + port).green);
87 // Launch browser
88 open('http://localhost:' + port);
89}
90
91start(process.env.PORT);