Merge pull request #770 from embark-framework/features/open-browser

open browser when Embark's webserver starts
This commit is contained in:
Iuri Matias 2018-09-04 13:51:57 -04:00 committed by GitHub
commit 7ee02525a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 105 additions and 36 deletions

View File

@ -228,6 +228,7 @@ class Engine {
}
webServerService(_options) {
_options.buildDir = this.config.buildDir;
this.registerModule('webserver', _options);
}

View File

@ -13,8 +13,7 @@ const Templates = {
define_web3_simple: require('./code_templates/define-web3-simple.js.ejs'),
web3_connector: require('./code_templates/web3-connector.js.ejs'),
do_when_loaded: require('./code_templates/do-when-loaded.js.ejs'),
exec_when_env_loaded: require('./code_templates/exec-when-env-loaded.js.ejs'),
embark_building_placeholder: require('./code_templates/embark-building-placeholder.html.ejs')
exec_when_env_loaded: require('./code_templates/exec-when-env-loaded.js.ejs')
};
class CodeGenerator {
@ -94,10 +93,6 @@ class CodeGenerator {
cb(self.generateContractCode(contract, gasLimit));
});
this.events.setCommandHandler('embark-building-placeholder', (cb) => {
self.buildPlaceholderPage(cb);
});
self.events.setCommandHandler('code-generator:embarkjs:provider-code', (cb) => {
cb(self.getEmbarkJsProviderCode());
});
@ -379,12 +374,6 @@ class CodeGenerator {
}
], cb);
}
buildPlaceholderPage(cb) {
let html = Templates.embark_building_placeholder({buildingMsg: __('Embark is building, please wait...')});
cb(html);
}
}
module.exports = CodeGenerator;

View File

@ -1,13 +1,20 @@
const fs = require('../../core/fs.js');
var {canonicalHost} = require('../../utils/host.js');
var utils = require('../../utils/utils.js');
var Server = require('./server.js');
const opn = require('opn');
require('ejs');
const Templates = {
embark_building_placeholder: require('./templates/embark-building-placeholder.html.ejs')
};
class WebServer {
constructor(embark, options) {
this.embark = embark;
this.logger = embark.logger;
this.events = embark.events;
this.buildDir = options.buildDir;
this.webServerConfig = embark.config.webServerConfig;
if (!this.webServerConfig.enabled) {
return;
@ -18,7 +25,13 @@ class WebServer {
this.events.emit("status", __("Starting Server"));
this.server = new Server({host: this.host, port: this.port});
this.server = new Server({
buildDir: this.buildDir,
events: this.events,
host: this.host,
port: this.port
});
this.testPort(() => {
this.listenToCommands();
this.registerConsoleCommands();
@ -60,25 +73,48 @@ class WebServer {
}
listenToCommands() {
this.events.setCommandHandler('start-webserver', (callback) => this.server.start(callback));
this.events.setCommandHandler('stop-webserver', (callback) => this.server.stop(callback));
this.events.setCommandHandler('build-placeholder', (cb) => this.buildPlaceholderPage(cb));
this.events.setCommandHandler('open-browser', (cb) => this.openBrowser(cb));
this.events.setCommandHandler('start-webserver', (cb) => this.server.start(cb));
this.events.setCommandHandler('stop-webserver', (cb) => this.server.stop(cb));
}
registerConsoleCommands() {
const self = this;
self.embark.registerConsoleCommand((cmd, _options) => {
return {
match: () => cmd === "webserver start",
process: (callback) => self.events.request("start-webserver", callback)
match: () => cmd === 'webserver start',
process: (cb) => self.events.request('start-webserver', cb)
};
});
self.embark.registerConsoleCommand((cmd, _options) => {
return {
match: () => cmd === "webserver stop",
process: (callback) => self.events.request("stop-webserver", callback)
match: () => cmd === 'webserver stop',
process: (cb) => self.events.request('stop-webserver', cb)
};
});
self.embark.registerConsoleCommand((cmd, _options) => {
return {
match: () => cmd === 'browser open',
process: (cb) => self.events.request('open-browser', cb)
};
});
}
buildPlaceholderPage(cb) {
let html = Templates.embark_building_placeholder({buildingMsg: __('Embark is building, please wait...')});
fs.mkdirpSync(this.buildDir); // create buildDir if it does not exist
fs.writeFile(utils.joinPath(this.buildDir, 'index.html'), html, cb);
}
openBrowser(cb) {
const _cb = () => { cb(); };
return opn(
`http://${canonicalHost(this.server.hostname)}:${this.server.port}`,
{wait: false}
).then(_cb, _cb); // fail silently, e.g. in a docker container
}
}

View File

@ -1,4 +1,5 @@
let finalhandler = require('finalhandler');
const async = require('async');
let http = require('http');
let serveStatic = require('serve-static');
const {canonicalHost, defaultHost, dockerHostSwap} = require('../../utils/host');
@ -6,31 +7,59 @@ require('http-shutdown').extend();
class Server {
constructor(options) {
this.dist = options.dist || 'dist/';
this.buildDir = options.buildDir;
this.events = options.events;
this.port = options.port || 8000;
this.hostname = dockerHostSwap(options.host) || defaultHost;
this.isFirstStart = true;
this.opened = false;
}
start(callback) {
if (this.server && this.server.listening) {
let message = __("a webserver is already running at") + " " +
("http://" + canonicalHost(this.hostname) +
":" + this.port).bold.underline.green;
("http://" + canonicalHost(this.hostname) +
":" + this.port).bold.underline.green;
return callback(null, message);
}
let serve = serveStatic(this.dist, {'index': ['index.html', 'index.htm']});
let serve = serveStatic(this.buildDir, {'index': ['index.html', 'index.htm']});
this.server = http.createServer(function onRequest(req, res) {
serve(req, res, finalhandler(req, res));
}).withShutdown();
const self = this;
this.server.listen(this.port, this.hostname, () => {
this.port = this.server.address().port;
callback(null, __("webserver available at") +
" " +
("http://" + canonicalHost(this.hostname) +
":" + this.port).bold.underline.green, this.port);
async.waterfall([
function createPlaceholderPage(next) {
if (!self.isFirstStart) {
return next();
}
self.isFirstStart = false;
self.events.request('build-placeholder', next);
},
function listen(next) {
self.server.listen(self.port, self.hostname, () => {
self.port = self.server.address().port;
next();
});
},
function openBrowser(next) {
if (self.opened) {
return next();
}
self.opened = true;
self.events.request('open-browser', next);
}
], function (err) {
if (err) {
return callback(err);
}
const msg = (
__('webserver available at') + ' ' +
('http://' + canonicalHost(self.hostname) + ':' + self.port).bold.underline.green
);
callback(null, msg, self.port);
});
}
@ -42,7 +71,6 @@ class Server {
callback(null, __("Webserver stopped"));
});
}
}
module.exports = Server;

View File

@ -5,7 +5,6 @@ const utils = require('../utils/utils.js');
const constants = require('../constants');
class Pipeline {
constructor(options) {
this.env = options.env;
this.buildDir = options.buildDir;
@ -16,6 +15,7 @@ class Pipeline {
this.plugins = options.plugins;
this.webpackConfigName = options.webpackConfigName;
this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
this.isFirstBuild = true;
}
build(abi, contractsJSON, path, callback) {
@ -29,10 +29,11 @@ class Pipeline {
async.waterfall([
function createPlaceholderPage(next){
self.events.request('embark-building-placeholder', (html) => {
fs.mkdirpSync(self.buildDir); // create dist/ folder if not already exists
fs.writeFile(utils.joinPath(self.buildDir, 'index.html'), html, next);
});
if (self.isFirstBuild) {
self.isFirstBuild = false;
return next();
}
self.events.request('build-placeholder', next);
},
function buildTheContracts(next) {
self.buildContracts(next);

13
package-lock.json generated
View File

@ -5272,6 +5272,11 @@
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
},
"is-wsl": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@ -6698,6 +6703,14 @@
"mimic-fn": "^1.0.0"
}
},
"opn": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
"integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
"requires": {
"is-wsl": "^1.1.0"
}
},
"optimist": {
"version": "0.3.7",
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",

View File

@ -66,6 +66,7 @@
"netcat": "^1.3.5",
"node-ipc": "^9.1.1",
"node-netcat": "^1.4.8",
"opn": "^5.3.0",
"ora": "^2.1.0",
"os-locale": "^2.1.0",
"parse-json": "^4.0.0",