├── .gitignore
├── test
├── index.css
└── index.html
├── package.json
├── bin
└── lr-http-server
├── README.md
└── src
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.sublime-*
--------------------------------------------------------------------------------
/test/index.css:
--------------------------------------------------------------------------------
1 | p {
2 | color: #ff5555;
3 | }
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | fsdfds fds fds
10 |
11 | dsfdsfds sdfsd fdsf dsf sdfsd f
12 |
13 | fdsfdsfds
14 | fdsfds
15 | fdsfds
16 |
17 |
18 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lr-http-server",
3 | "version": "0.1.5",
4 | "description": "An HTTP server with livereload included",
5 | "main": "src/index.js",
6 | "bin": {
7 | "lr-http-server": "bin/lr-http-server",
8 | "lrhs": "bin/lr-http-server"
9 | },
10 | "scripts": {},
11 | "repository": {
12 | "type": "git",
13 | "url": "git@github.com:manuelcabral/lr-http-server.git"
14 | },
15 | "author": "Manuel Cabral (m.cabral@digisfera.pt)",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/manuelcabral/lr-http-server/issues"
19 | },
20 | "dependencies": {
21 | "commander": "^2.0.0",
22 | "connect": "^3.4.1",
23 | "connect-livereload": "^0.5.4",
24 | "gaze": "^1.1.0",
25 | "lodash.debounce": "^4.0.8",
26 | "open": "0.0.5",
27 | "serve-index": "^1.8.0",
28 | "serve-static": "^1.11.1",
29 | "tiny-lr": "^0.2.1"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/bin/lr-http-server:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var simpleHttpMime = require('../src/index.js');
4 | var program = require('commander');
5 |
6 | function list(val) {
7 | return val.split(',');
8 | }
9 |
10 | program
11 | .option('-p, --port ', 'Port number', parseInt)
12 | .option('-d, --dir ', 'Directory to serve')
13 | .option('-u, --url ', 'Url to opening file')
14 | .option('-l, --livereload ', 'Port for the livereload server. Disabled if `false`')
15 | .option('-w, --watchFiles ', 'Comma-separated list of glob patterns of files to watch', list)
16 | .option('-b, --disableBrowserOpen', 'Disable opening a browser window on the server root')
17 | .option('-e, --extensions ', 'Comma-separated list of extensions which will be added to file name if the file not found (think like /foo -> /foo.html)', list)
18 | .option('-D, --debounce-delay ', 'The applied delay for file watching in milliseconds, it can be used for grouping changes', parseFloat)
19 | .parse(process.argv);
20 |
21 | simpleHttpMime(program.port, program.dir, program.url, program.livereload, program.watchFiles, !program.disableBrowserOpen, program.extensions, program.debounceDelay);
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # lr-http-server
2 |
3 | An HTTP server with livereload included. If a file inside the folder being served is changed, added or deleted, the browser will automatically reload.
4 |
5 |
6 | ## Installing
7 |
8 | npm install -g lr-http-server
9 |
10 | ## Usage
11 |
12 | lr-http-server [-p ] [-d ] [-l livereloadport] [-w < watchPaths || false >] [-b]
13 |
14 | **port** (default *8080*): Port to listen on
15 |
16 | **dir** (default *.*): Folder to serve
17 |
18 | **url** (default *empty*): Path to open the specific page. *e.g.* `/#/main`
19 |
20 | **livereloadport** (default *35729*): Port for the livereload server. If `false` the livereload is disabled.
21 |
22 | **watchPaths**: Comma-separated list of glob patterns for the files to watch. *e.g.* `**/*.js,**/*.css,**/*.html,**/*.xml`
23 |
24 | **b**: disable browser open
25 |
26 | ## Examples
27 |
28 | Default usage
29 |
30 | > lr-http-server
31 |
32 | HTTP server listening on port 8080
33 | Serving
34 | Livereload listening on port 35729
35 | Watching files:
36 | '/**/*.html'
37 | '/**/*.js'
38 | '/**/*.css'
39 | '/**/*.xml'
40 |
41 | All options
42 |
43 | > lr-http-server -p 80 -d src/ -u /#/main -l 30000 -w **/*.css,*.html
44 |
45 | HTTP server listening on port 80
46 | Serving /src
47 | Open page in browser /src/#/main
48 | Livereload listening on port 30000
49 | Watching files:
50 | /src/**/*.css
51 | /src/*.html
52 |
53 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | var connect = require('connect'),
2 | serveStatic = require('serve-static'),
3 | serveIndex = require('serve-index'),
4 | path = require('path'),
5 | gaze = require('gaze'),
6 | open = require('open'),
7 | tinylr = require('tiny-lr'),
8 | debounce = require('lodash.debounce');
9 |
10 |
11 | module.exports = function(port, dir, url, livereloadPort, watchFiles, openBrowser, extensions, debounceDelay) {
12 |
13 | port = port || 8080;
14 | dir = dir || '.';
15 | url = url || '';
16 |
17 | if(livereloadPort === 'false' || livereloadPort === false)
18 | livereloadPort = false;
19 | else
20 | livereloadPort = livereloadPort || 35729;
21 |
22 | watchFiles = watchFiles || [ '**/*.html', '**/*.js', '**/*.css', '**/*.xml' ];
23 |
24 | extensions = (extensions && extensions.length > 0) ? extensions : false;
25 |
26 | absoluteDir = path.resolve(dir);
27 |
28 | var absoluteWatchFiles = watchFiles.map(function(relativePath) {
29 | return path.join(absoluteDir, relativePath);
30 | });
31 |
32 |
33 | var server = connect();
34 |
35 |
36 | if(livereloadPort) {
37 | server.use(require('connect-livereload')({ port: livereloadPort }));
38 |
39 | var livereloadServer = tinylr();
40 |
41 | livereloadServer.listen(livereloadPort, function(err) {
42 | if(err) {
43 | console.error("Livereload not started", err);
44 | return;
45 | }
46 |
47 | console.log('Livereload listening on port %s', livereloadPort);
48 |
49 | console.log("Watching files:");
50 | for(var f in absoluteWatchFiles) {
51 | console.log(' ' + absoluteWatchFiles[f]);
52 | }
53 | });
54 |
55 | gaze(watchFiles, {cwd: absoluteDir}, function(err, watcher) {
56 | if(err) {
57 | console.error("Unable to watch files", err);
58 | }
59 | var files = [];
60 | var changed = debounce(function() {
61 | console.log("Sending changes:\n\t%s", files.join("\n\t"));
62 | livereloadServer.changed({body:{files:files}});
63 | files = [];
64 | }, debounceDelay);
65 | this.on('all', function(event, filepath) {
66 | console.log("Watch: " + filepath + ' was ' + event);
67 | files.push(filepath);
68 | changed();
69 | });
70 | });
71 | }
72 |
73 | server.use(serveStatic(absoluteDir, { extensions: extensions }))
74 | .use(serveIndex(absoluteDir))
75 | .listen(port);
76 |
77 | console.log("HTTP server listening on port " + port + "\nServing " + absoluteDir);
78 |
79 | if(openBrowser) { open("http://127.0.0.1:" + port + url); }
80 |
81 | };
82 |
--------------------------------------------------------------------------------