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 @@ [](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
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
27177
16
448
185
2
2