├── .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 | --------------------------------------------------------------------------------