live-server
Advanced tools
Comparing version 0.8.2 to 0.9.0
73
index.js
@@ -16,3 +16,6 @@ #!/usr/bin/env node | ||
var LiveServer = {}; | ||
var LiveServer = { | ||
server: null, | ||
watchers: [] | ||
}; | ||
@@ -33,3 +36,4 @@ function escape(html){ | ||
var hasNoOrigin = !req.headers.origin; | ||
var doInject = false; | ||
var injectCandidates = [ "</body>", "</svg>" ]; | ||
var injectTag = null; | ||
@@ -45,7 +49,12 @@ function directory() { | ||
var x = path.extname(filepath).toLocaleLowerCase(), | ||
possibleExtensions = ["", ".html", ".htm", ".xhtml", ".php"]; | ||
possibleExtensions = [ "", ".html", ".htm", ".xhtml", ".php", ".svg" ]; | ||
if (hasNoOrigin && (possibleExtensions.indexOf(x) > -1)) { | ||
// TODO: Sync file read here is not nice, but we need to determine if the html should be injected or not | ||
var contents = fs.readFileSync(filepath, "utf8"); | ||
doInject = contents.indexOf("</body>") > -1; | ||
for (var i = 0; i < injectCandidates.length; ++i) { | ||
if (contents.indexOf(injectCandidates[i]) > -1) { | ||
injectTag = injectCandidates[i]; | ||
break; | ||
} | ||
} | ||
} | ||
@@ -60,3 +69,3 @@ } | ||
function inject(stream) { | ||
if (doInject) { | ||
if (injectTag) { | ||
// We need to modify the length given to browser | ||
@@ -67,3 +76,3 @@ var len = INJECTED_CODE.length + res.getHeader('Content-Length'); | ||
stream.pipe = function(res) { | ||
originalPipe.call(stream, es.replace(new RegExp("</body>", "i"), INJECTED_CODE + "</body>")).pipe(res); | ||
originalPipe.call(stream, es.replace(new RegExp(injectTag, "i"), INJECTED_CODE + injectTag)).pipe(res); | ||
}; | ||
@@ -102,2 +111,3 @@ } | ||
* @param open {string} Subpath to open in browser, use false to suppress launch (default: server root) | ||
* @param mount {array} Mount directories onto a route, e.g. [['/components', './node_modules']]. | ||
* @param logLevel {number} 0 = errors only, 1 = some, 2 = lots | ||
@@ -112,2 +122,4 @@ * @param file {string} Path to the entry point file | ||
var root = options.root || process.cwd(); | ||
var mount = options.mount || []; | ||
var watchPaths = [root]; | ||
var logLevel = options.logLevel === undefined ? 2 : options.logLevel; | ||
@@ -120,6 +132,14 @@ var openPath = (options.open === undefined || options.open === true) ? | ||
var wait = options.wait || 0; | ||
var browser = options.browser || null; | ||
// Setup a web server | ||
var app = connect() | ||
.use(staticServerHandler) // Custom static server | ||
var app = connect(); | ||
mount.forEach(function(mountRule) { | ||
var mountPath = path.resolve(process.cwd(), mountRule[1]); | ||
watchPaths.push(mountPath); | ||
app.use(mountRule[0], staticServer(mountPath)); | ||
if (logLevel >= 1) | ||
console.log('Mapping %s to "%s"', mountRule[0], mountPath); | ||
}); | ||
app.use(staticServerHandler) // Custom static server | ||
.use(entryPoint(staticServerHandler, file)) | ||
@@ -135,6 +155,9 @@ .use(connect.directory(root, { icons: true })); | ||
var serveURL = 'http://' + host + ':' + port; | ||
console.log('%s is already in use. Trying another port.'.red, serveURL); | ||
console.log('%s is already in use. Trying another port.'.yellow, serveURL); | ||
setTimeout(function() { | ||
server.listen(0, host); | ||
}, 1000); | ||
} else { | ||
console.error(e.toString().red); | ||
LiveServer.shutdown(); | ||
} | ||
@@ -145,9 +168,17 @@ }); | ||
server.addListener('listening', function(e) { | ||
LiveServer.server = server; | ||
var address = server.address(); | ||
var serveHost = address.address === "0.0.0.0" ? "127.0.0.1" : address.address; | ||
var openHost = host === "0.0.0.0" ? "127.0.0.1" : host; | ||
var serveURL = 'http://' + serveHost + ':' + address.port; | ||
var openURL = 'http://' + openHost + ':' + address.port; | ||
// Output | ||
if (logLevel >= 1) { | ||
console.log(("Serving \"%s\" at %s").green, root, serveURL); | ||
if (serveURL === openURL) | ||
console.log(("Serving \"%s\" at %s").green, root, serveURL); | ||
else | ||
console.log(("Serving \"%s\" at %s (%s)").green, root, openURL, serveURL); | ||
} | ||
@@ -157,3 +188,3 @@ | ||
if (openPath !== null) | ||
open(serveURL + openPath); | ||
open(openURL + openPath, {app: browser}); | ||
}); | ||
@@ -196,3 +227,3 @@ | ||
watchr.watch({ | ||
path: root, | ||
paths: watchPaths, | ||
ignorePaths: options.ignore || false, | ||
@@ -221,6 +252,24 @@ ignoreCommonPatterns: true, | ||
} | ||
}, | ||
next: function(err, watchers) { | ||
if (err) | ||
console.error("Error watching files:".red, err); | ||
LiveServer.watchers = watchers; | ||
} | ||
}); | ||
return server; | ||
}; | ||
LiveServer.shutdown = function() { | ||
var watchers = LiveServer.watchers; | ||
if (watchers) { | ||
for (var i = 0; i < watchers.length; ++i) | ||
watchers[i].close(); | ||
} | ||
var server = LiveServer.server; | ||
if (server) | ||
server.close(); | ||
}; | ||
module.exports = LiveServer; |
@@ -10,2 +10,3 @@ #!/usr/bin/env node | ||
open: true, | ||
mount: [], | ||
logLevel: 2 | ||
@@ -52,2 +53,6 @@ }; | ||
} | ||
else if (arg.indexOf("--browser=") > -1) { | ||
opts.browser = arg.substring(10).split(","); | ||
process.argv.splice(i, 1); | ||
} | ||
else if (arg.indexOf("--entry-file=") > -1) { | ||
@@ -64,2 +69,9 @@ var file = arg.substring(13); | ||
} | ||
else if (arg.indexOf("--mount=") > -1) { | ||
// e.g. "--mount=/components:./node_modules" will be ['/components', '<process.cwd()>/node_modules'] | ||
var mountRule = arg.substring(8).split(":"); | ||
mountRule[1] = path.resolve(process.cwd(), mountRule[1]); | ||
opts.mount.push(mountRule); | ||
process.argv.splice(i, 1); | ||
} | ||
else if (arg.indexOf("--wait=") > -1) { | ||
@@ -79,5 +91,10 @@ var waitString = arg.substring(7); | ||
else if (arg == "--help" || arg == "-h") { | ||
console.log('Usage: live-server [-v|--version] [-h|--help] [-q|--quiet] [--port=PORT] [--host=HOST] [--open=PATH] [--no-browser] [--ignore=PATH] [--entry-file=PATH] [--wait=MILLISECONDS] [PATH]'); | ||
console.log('Usage: live-server [-v|--version] [-h|--help] [-q|--quiet] [--port=PORT] [--host=HOST] [--open=PATH] [--no-browser] [--browser=BROWSER] [--ignore=PATH] [--entry-file=PATH] [--mount=ROUTE:PATH] [--wait=MILLISECONDS] [PATH]'); | ||
process.exit(); | ||
} | ||
else if (arg == "--test") { | ||
// Hidden param for tests to exit automatically | ||
setTimeout(liveServer.shutdown, 500); | ||
process.argv.splice(i, 1); | ||
} | ||
} | ||
@@ -84,0 +101,0 @@ |
{ | ||
"name": "live-server", | ||
"version": "0.8.2", | ||
"version": "0.9.0", | ||
"description": "simple development http server with live reload capability", | ||
@@ -24,4 +24,9 @@ "keywords": [ | ||
}, | ||
"devDependencies": { | ||
"mocha": "^2.3.3", | ||
"supertest": "1.0.1" | ||
}, | ||
"scripts": { | ||
"test": "jshint *.js; eslint *.js" | ||
"test": "mocha test", | ||
"lint": "jshint *.js; eslint *.js" | ||
}, | ||
@@ -28,0 +33,0 @@ "bin": { |
@@ -48,2 +48,3 @@ [![view on npm](http://img.shields.io/npm/v/live-server.svg)](https://www.npmjs.org/package/live-server) | ||
* `--no-browser` - suppress automatic web browser launching | ||
* `--browser=BROWSER` - specify browser to use instead of system default | ||
* `--quiet` - suppress logging | ||
@@ -53,2 +54,3 @@ * `--open=PATH` - launch browser to PATH instead of server root | ||
* `--entry-file=PATH` - serve this file in place of missing files (useful for single page apps) | ||
* `--mount=ROUTE:PATH` - serve the paths contents under the defined route (multiple definitions possible) | ||
* `--wait=MILLISECONDS` - wait for all changes, before reloading | ||
@@ -77,2 +79,3 @@ * `--help | -h` - display terse usage hint and exit | ||
wait: 1000 // Waits for all changes, before reloading. Defaults to 0 sec. | ||
mount: [['/components', './node_modules']] // Mount a directory to a route. | ||
}; | ||
@@ -104,2 +107,10 @@ liveServer.start(params); | ||
* v0.9.0 | ||
- `--mount=ROUTE:PATH` cli option to specify alternative routes to paths (@pmentz) | ||
- `--browser=BROWSER` cli option to specify browser to use (@sakiv) | ||
- Improved error reporting | ||
- Basic support for injecting the reload code to SVG files (@dotnetCarpenter, @tapio) | ||
- LiveServer.shutdown() function to close down the server and file watchers | ||
- If host parameter is given, use it for browser URL instead of resolved IP | ||
- Initial testing framework (@harrytruong, @evanplaice, @tapio) | ||
* v0.8.2 | ||
@@ -106,0 +117,0 @@ - Load initial settings from `~/.live-server.json` if exists (@mikker) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27177
16
448
185
2
2